diff --git a/flixpy/flix/extension/client.py b/flixpy/flix/extension/client.py index 466327a..976bddc 100644 --- a/flixpy/flix/extension/client.py +++ b/flixpy/flix/extension/client.py @@ -239,6 +239,12 @@ def status(self) -> types.Status: return status + @property + def selected_panels(self) -> list[types.PanelSelection]: + if self.online and self.project.sequence_revision: + return self.panel_browser_status.revision_status.panel_selection + return [] + async def _on_connect(self) -> None: logger.info("connected to Flix Client, subscribing to events") events = models.SubscribeRequest( @@ -433,6 +439,21 @@ async def get_status(self) -> types.PanelBrowserStatus: return types.PanelBrowserStatus.from_model(resp) + async def get_current_versions(self) -> types.VersionResponse: + """Get details about the current status of the Flix Client. + + Returns: + An object containing information about the current Flix Client status. + """ + from .extension_api.api.info import info_controller_get + + resp = _assert_response( + models.InfoResponse, + await info_controller_get.asyncio_detailed(client=await self._get_registered_client()), + ) + + return types.VersionResponse.from_model(resp) + async def import_panels( self, paths: list[str], diff --git a/flixpy/flix/extension/extension_api.yaml b/flixpy/flix/extension/extension_api.yaml index cda9203..ce7e5a0 100644 --- a/flixpy/flix/extension/extension_api.yaml +++ b/flixpy/flix/extension/extension_api.yaml @@ -68,11 +68,14 @@ info: ### Step 5: All done That's it! You're now ready to interact with the Flix Client and ready to turn “My First Flix Extension” into the best thing ever. Although, maybe come up with a better name first. - version: v1 - contact: {} + version: v1.1.0 + contact: + url: http://www.foundry.com + email: support@foundry.com license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html + termsOfService: https://www.foundry.com/eula servers: - url: http://localhost:3000 description: Flix Client API @@ -80,6 +83,9 @@ tags: - name: Health Check description: | The health check endpoint is a basic test entrypoint for the Flix Client API and will always return a 200 OK response when the API is available. This endpoint can be used as a sanity check to validate connections to Flix before first connecting or after a disconnect. + - name: Info + description: | + The Info endpoint provides essential information about the supported versions and the current client version. This endpoint consistently returns a 200 OK response when the API is operational. - name: API Registration description: | Most of the Flix Client API is gated behind a simple API registration process. Each API consumer must first register with Flix by sending a POST request to http://localhost:3000/registration. The token in the registration response should be attached as a bearer token in the authorization header with future requests. To validate the registration, do a GET request to the same registration endpoint along with the auth header, and the registered API consumer details should be returned. @@ -107,6 +113,9 @@ tags: - name: Media Object Download description: | The download endpoint provides the ability for an extension to request a specific asset from the Flix Server and have the Flix Client download it to a specified location. Before using this endpoint, you will need to figure out the ID of the asset to be downloaded and the type of the media object required, either using the other API endpoints or from the Flix Server API. Requests to the download API endpoint will begin the download immediately and will not complete until the download has finished, which means the request may be long-lived. + - name: Preferences + description: | + The preferences endpoint provides a lookup for the current Flix Client user preferences. A GET request to this endpoint will return the full list of preferences currently set in the client. This can optionally be filtered down by specifying a subset of properties via the `keys` query parameter. This can either be a comma separated string, or be specified multiple times for each desired preference. paths: /health: get: @@ -119,6 +128,21 @@ paths: description: '' tags: - Health Check + /info: + get: + operationId: InfoController_get + summary: Flix Client details + description: Provides details of current Flix Client and GRC API. Always returns a 200 response. + parameters: [] + responses: + '200': + description: Flix Client details successfully returned + content: + application/json: + schema: + $ref: '#/components/schemas/InfoResponse' + tags: + - Info /registration: post: operationId: RegistrationController_registerClient @@ -329,18 +353,18 @@ paths: security: - bearer: [] /preferences: - post: - operationId: PreferencesController_post + get: + operationId: PreferencesController_lookupPreferences summary: Get Flix Preferences Values - parameters: [] - requestBody: - required: true - content: - application/json: - schema: - type: array - items: - type: string + parameters: + - name: keys + required: false + in: query + description: A list of keys for which to return the user preference values. Can either be a comma-separated list, or specified multiple times. + schema: + type: array + items: + type: string responses: '200': description: Returns a Config object for a provided list of preferences set in the Flix Client @@ -366,6 +390,20 @@ components: bearerFormat: JWT type: http schemas: + InfoResponse: + type: object + properties: + flixVersion: + type: string + description: Current Flix Client version. + supportedApiVersions: + description: Supported GRC API versions. + type: array + items: + type: string + required: + - flixVersion + - supportedApiVersions SubscribeRequest: type: object properties: @@ -977,12 +1015,29 @@ components: - episode - sequence - sequenceRevision + PanelSelectionResponse: + type: object + properties: + id: + type: integer + description: The ID of the selected panel. + revisionId: + type: integer + description: The revision of the selected panel. + index: + type: integer + description: The current index in the panel browser of the selected panel. + required: + - id + - revisionId + - index RevisionStatusResponse: type: object properties: selectedPanels: type: array - description: A list of the currently selected panels. + description: A list of the currently selected panel IDs. + deprecated: true items: type: integer canSave: @@ -994,6 +1049,11 @@ components: canExport: type: boolean description: Whether the user has permission to export files from the current revision. + panelSelection: + description: A list of the currently selected panel details, including ID. + type: array + items: + $ref: '#/components/schemas/PanelSelectionResponse' required: - selectedPanels - canSave diff --git a/flixpy/flix/extension/extension_api/api/info/__init__.py b/flixpy/flix/extension/extension_api/api/info/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/flixpy/flix/extension/extension_api/api/info/info_controller_get.py b/flixpy/flix/extension/extension_api/api/info/info_controller_get.py new file mode 100644 index 0000000..7989978 --- /dev/null +++ b/flixpy/flix/extension/extension_api/api/info/info_controller_get.py @@ -0,0 +1,134 @@ +from http import HTTPStatus +from typing import Any, Dict, Optional, Union + +import httpx + +from ... import errors +from ...client import AuthenticatedClient, Client +from ...models.info_response import InfoResponse +from ...types import Response + + +def _get_kwargs() -> Dict[str, Any]: + pass + + return { + "method": "get", + "url": "/info", + } + + +def _parse_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Optional[InfoResponse]: + if response.status_code == HTTPStatus.OK: + response_200 = InfoResponse.from_dict(response.json()) + + return response_200 + if client.raise_on_unexpected_status: + raise errors.UnexpectedStatus(response.status_code, response.content) + else: + return None + + +def _build_response( + *, client: Union[AuthenticatedClient, Client], response: httpx.Response +) -> Response[InfoResponse]: + return Response( + status_code=HTTPStatus(response.status_code), + content=response.content, + headers=response.headers, + parsed=_parse_response(client=client, response=response), + ) + + +def sync_detailed( + *, + client: Union[AuthenticatedClient, Client], +) -> Response[InfoResponse]: + """Flix Client details + + Provides details of current Flix Client and GRC API. Always returns a 200 response. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[InfoResponse] + """ + + kwargs = _get_kwargs() + + response = client.get_httpx_client().request( + **kwargs, + ) + + return _build_response(client=client, response=response) + + +def sync( + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[InfoResponse]: + """Flix Client details + + Provides details of current Flix Client and GRC API. Always returns a 200 response. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + InfoResponse + """ + + return sync_detailed( + client=client, + ).parsed + + +async def asyncio_detailed( + *, + client: Union[AuthenticatedClient, Client], +) -> Response[InfoResponse]: + """Flix Client details + + Provides details of current Flix Client and GRC API. Always returns a 200 response. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + Response[InfoResponse] + """ + + kwargs = _get_kwargs() + + response = await client.get_async_httpx_client().request(**kwargs) + + return _build_response(client=client, response=response) + + +async def asyncio( + *, + client: Union[AuthenticatedClient, Client], +) -> Optional[InfoResponse]: + """Flix Client details + + Provides details of current Flix Client and GRC API. Always returns a 200 response. + + Raises: + errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. + httpx.TimeoutException: If the request takes longer than Client.timeout. + + Returns: + InfoResponse + """ + + return ( + await asyncio_detailed( + client=client, + ) + ).parsed diff --git a/flixpy/flix/extension/extension_api/api/preferences/preferences_controller_post.py b/flixpy/flix/extension/extension_api/api/preferences/preferences_controller_lookup_preferences.py similarity index 60% rename from flixpy/flix/extension/extension_api/api/preferences/preferences_controller_post.py rename to flixpy/flix/extension/extension_api/api/preferences/preferences_controller_lookup_preferences.py index 45b13fb..5ea136e 100644 --- a/flixpy/flix/extension/extension_api/api/preferences/preferences_controller_post.py +++ b/flixpy/flix/extension/extension_api/api/preferences/preferences_controller_lookup_preferences.py @@ -5,32 +5,44 @@ from ... import errors from ...client import AuthenticatedClient, Client -from ...models.preferences_controller_post_response_200 import ( - PreferencesControllerPostResponse200, +from ...models.preferences_controller_lookup_preferences_response_200 import ( + PreferencesControllerLookupPreferencesResponse200, ) -from ...types import Response +from ...types import UNSET, Response, Unset def _get_kwargs( *, - json_body: List[str], + keys: Union[Unset, None, List[str]] = UNSET, ) -> Dict[str, Any]: pass - json_json_body = json_body + params: Dict[str, Any] = {} + json_keys: Union[Unset, None, List[str]] = UNSET + if not isinstance(keys, Unset): + if keys is None: + json_keys = None + else: + json_keys = keys + + params["keys"] = json_keys + + params = {k: v for k, v in params.items() if v is not UNSET and v is not None} return { - "method": "post", + "method": "get", "url": "/preferences", - "json": json_json_body, + "params": params, } def _parse_response( *, client: Union[AuthenticatedClient, Client], response: httpx.Response -) -> Optional[Union[Any, PreferencesControllerPostResponse200]]: +) -> Optional[Union[Any, PreferencesControllerLookupPreferencesResponse200]]: if response.status_code == HTTPStatus.OK: - response_200 = PreferencesControllerPostResponse200.from_dict(response.json()) + response_200 = PreferencesControllerLookupPreferencesResponse200.from_dict( + response.json() + ) return response_200 if response.status_code == HTTPStatus.BAD_REQUEST: @@ -44,7 +56,7 @@ def _parse_response( def _build_response( *, client: Union[AuthenticatedClient, Client], response: httpx.Response -) -> Response[Union[Any, PreferencesControllerPostResponse200]]: +) -> Response[Union[Any, PreferencesControllerLookupPreferencesResponse200]]: return Response( status_code=HTTPStatus(response.status_code), content=response.content, @@ -56,23 +68,23 @@ def _build_response( def sync_detailed( *, client: AuthenticatedClient, - json_body: List[str], -) -> Response[Union[Any, PreferencesControllerPostResponse200]]: + keys: Union[Unset, None, List[str]] = UNSET, +) -> Response[Union[Any, PreferencesControllerLookupPreferencesResponse200]]: """Get Flix Preferences Values Args: - json_body (List[str]): + keys (Union[Unset, None, List[str]]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Union[Any, PreferencesControllerPostResponse200]] + Response[Union[Any, PreferencesControllerLookupPreferencesResponse200]] """ kwargs = _get_kwargs( - json_body=json_body, + keys=keys, ) response = client.get_httpx_client().request( @@ -85,47 +97,47 @@ def sync_detailed( def sync( *, client: AuthenticatedClient, - json_body: List[str], -) -> Optional[Union[Any, PreferencesControllerPostResponse200]]: + keys: Union[Unset, None, List[str]] = UNSET, +) -> Optional[Union[Any, PreferencesControllerLookupPreferencesResponse200]]: """Get Flix Preferences Values Args: - json_body (List[str]): + keys (Union[Unset, None, List[str]]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Union[Any, PreferencesControllerPostResponse200] + Union[Any, PreferencesControllerLookupPreferencesResponse200] """ return sync_detailed( client=client, - json_body=json_body, + keys=keys, ).parsed async def asyncio_detailed( *, client: AuthenticatedClient, - json_body: List[str], -) -> Response[Union[Any, PreferencesControllerPostResponse200]]: + keys: Union[Unset, None, List[str]] = UNSET, +) -> Response[Union[Any, PreferencesControllerLookupPreferencesResponse200]]: """Get Flix Preferences Values Args: - json_body (List[str]): + keys (Union[Unset, None, List[str]]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Response[Union[Any, PreferencesControllerPostResponse200]] + Response[Union[Any, PreferencesControllerLookupPreferencesResponse200]] """ kwargs = _get_kwargs( - json_body=json_body, + keys=keys, ) response = await client.get_async_httpx_client().request(**kwargs) @@ -136,24 +148,24 @@ async def asyncio_detailed( async def asyncio( *, client: AuthenticatedClient, - json_body: List[str], -) -> Optional[Union[Any, PreferencesControllerPostResponse200]]: + keys: Union[Unset, None, List[str]] = UNSET, +) -> Optional[Union[Any, PreferencesControllerLookupPreferencesResponse200]]: """Get Flix Preferences Values Args: - json_body (List[str]): + keys (Union[Unset, None, List[str]]): Raises: errors.UnexpectedStatus: If the server returns an undocumented status code and Client.raise_on_unexpected_status is True. httpx.TimeoutException: If the request takes longer than Client.timeout. Returns: - Union[Any, PreferencesControllerPostResponse200] + Union[Any, PreferencesControllerLookupPreferencesResponse200] """ return ( await asyncio_detailed( client=client, - json_body=json_body, + keys=keys, ) ).parsed diff --git a/flixpy/flix/extension/extension_api/models/__init__.py b/flixpy/flix/extension/extension_api/models/__init__.py index dd24fb1..4439ba3 100644 --- a/flixpy/flix/extension/extension_api/models/__init__.py +++ b/flixpy/flix/extension/extension_api/models/__init__.py @@ -13,6 +13,7 @@ from .episode_details_dto import EpisodeDetailsDto from .full_panel_annotate_request import FullPanelAnnotateRequest from .full_panel_request import FullPanelRequest +from .info_response import InfoResponse from .open_file_event import OpenFileEvent from .open_file_panel_data import OpenFilePanelData from .open_source_file_data import OpenSourceFileData @@ -20,9 +21,10 @@ from .panel_request_item import PanelRequestItem from .panel_request_response import PanelRequestResponse from .panel_request_source_file import PanelRequestSourceFile +from .panel_selection_response import PanelSelectionResponse from .ping_event import PingEvent -from .preferences_controller_post_response_200 import ( - PreferencesControllerPostResponse200, +from .preferences_controller_lookup_preferences_response_200 import ( + PreferencesControllerLookupPreferencesResponse200, ) from .project_details_dto import ProjectDetailsDto from .project_ids_dto import ProjectIdsDto @@ -70,6 +72,7 @@ "EpisodeDetailsDto", "FullPanelAnnotateRequest", "FullPanelRequest", + "InfoResponse", "OpenFileEvent", "OpenFilePanelData", "OpenSourceFileData", @@ -77,8 +80,9 @@ "PanelRequestItem", "PanelRequestResponse", "PanelRequestSourceFile", + "PanelSelectionResponse", "PingEvent", - "PreferencesControllerPostResponse200", + "PreferencesControllerLookupPreferencesResponse200", "ProjectDetailsDto", "ProjectIdsDto", "PsConfiguration", diff --git a/flixpy/flix/extension/extension_api/models/info_response.py b/flixpy/flix/extension/extension_api/models/info_response.py new file mode 100644 index 0000000..8dfb601 --- /dev/null +++ b/flixpy/flix/extension/extension_api/models/info_response.py @@ -0,0 +1,65 @@ +from typing import Any, Dict, List, Type, TypeVar, cast + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="InfoResponse") + + +@_attrs_define +class InfoResponse: + """ + Attributes: + flix_version (str): Current Flix Client version. + supported_api_versions (List[str]): Supported GRC API versions. + """ + + flix_version: str + supported_api_versions: List[str] + additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + flix_version = self.flix_version + supported_api_versions = self.supported_api_versions + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "flixVersion": flix_version, + "supportedApiVersions": supported_api_versions, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + flix_version = d.pop("flixVersion") + + supported_api_versions = cast(List[str], d.pop("supportedApiVersions")) + + info_response = cls( + flix_version=flix_version, + supported_api_versions=supported_api_versions, + ) + + info_response.additional_properties = d + return info_response + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/flixpy/flix/extension/extension_api/models/panel_selection_response.py b/flixpy/flix/extension/extension_api/models/panel_selection_response.py new file mode 100644 index 0000000..24dfd35 --- /dev/null +++ b/flixpy/flix/extension/extension_api/models/panel_selection_response.py @@ -0,0 +1,72 @@ +from typing import Any, Dict, List, Type, TypeVar + +from attrs import define as _attrs_define +from attrs import field as _attrs_field + +T = TypeVar("T", bound="PanelSelectionResponse") + + +@_attrs_define +class PanelSelectionResponse: + """ + Attributes: + id (int): The ID of the selected panel. + revision_id (int): The revision of the selected panel. + index (int): The current index in the panel browser of the selected panel. + """ + + id: int + revision_id: int + index: int + additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict) + + def to_dict(self) -> Dict[str, Any]: + id = self.id + revision_id = self.revision_id + index = self.index + + field_dict: Dict[str, Any] = {} + field_dict.update(self.additional_properties) + field_dict.update( + { + "id": id, + "revisionId": revision_id, + "index": index, + } + ) + + return field_dict + + @classmethod + def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + d = src_dict.copy() + id = d.pop("id") + + revision_id = d.pop("revisionId") + + index = d.pop("index") + + panel_selection_response = cls( + id=id, + revision_id=revision_id, + index=index, + ) + + panel_selection_response.additional_properties = d + return panel_selection_response + + @property + def additional_keys(self) -> List[str]: + return list(self.additional_properties.keys()) + + def __getitem__(self, key: str) -> Any: + return self.additional_properties[key] + + def __setitem__(self, key: str, value: Any) -> None: + self.additional_properties[key] = value + + def __delitem__(self, key: str) -> None: + del self.additional_properties[key] + + def __contains__(self, key: str) -> bool: + return key in self.additional_properties diff --git a/flixpy/flix/extension/extension_api/models/preferences_controller_post_response_200.py b/flixpy/flix/extension/extension_api/models/preferences_controller_lookup_preferences_response_200.py similarity index 81% rename from flixpy/flix/extension/extension_api/models/preferences_controller_post_response_200.py rename to flixpy/flix/extension/extension_api/models/preferences_controller_lookup_preferences_response_200.py index 8fd1e01..7568371 100644 --- a/flixpy/flix/extension/extension_api/models/preferences_controller_post_response_200.py +++ b/flixpy/flix/extension/extension_api/models/preferences_controller_lookup_preferences_response_200.py @@ -3,11 +3,11 @@ from attrs import define as _attrs_define from attrs import field as _attrs_field -T = TypeVar("T", bound="PreferencesControllerPostResponse200") +T = TypeVar("T", bound="PreferencesControllerLookupPreferencesResponse200") @_attrs_define -class PreferencesControllerPostResponse200: +class PreferencesControllerLookupPreferencesResponse200: """ """ additional_properties: Dict[str, Union[bool, int, str]] = _attrs_field( @@ -26,7 +26,7 @@ def to_dict(self) -> Dict[str, Any]: @classmethod def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: d = src_dict.copy() - preferences_controller_post_response_200 = cls() + preferences_controller_lookup_preferences_response_200 = cls() additional_properties = {} for prop_name, prop_dict in d.items(): @@ -38,10 +38,10 @@ def _parse_additional_property(data: object) -> Union[bool, int, str]: additional_properties[prop_name] = additional_property - preferences_controller_post_response_200.additional_properties = ( + preferences_controller_lookup_preferences_response_200.additional_properties = ( additional_properties ) - return preferences_controller_post_response_200 + return preferences_controller_lookup_preferences_response_200 @property def additional_keys(self) -> List[str]: diff --git a/flixpy/flix/extension/extension_api/models/revision_status_response.py b/flixpy/flix/extension/extension_api/models/revision_status_response.py index 074882c..cfa5a0f 100644 --- a/flixpy/flix/extension/extension_api/models/revision_status_response.py +++ b/flixpy/flix/extension/extension_api/models/revision_status_response.py @@ -1,8 +1,14 @@ -from typing import Any, Dict, List, Type, TypeVar, cast +from typing import TYPE_CHECKING, Any, Dict, List, Type, TypeVar, Union, cast from attrs import define as _attrs_define from attrs import field as _attrs_field +from ..types import UNSET, Unset + +if TYPE_CHECKING: + from ..models.panel_selection_response import PanelSelectionResponse + + T = TypeVar("T", bound="RevisionStatusResponse") @@ -10,16 +16,19 @@ class RevisionStatusResponse: """ Attributes: - selected_panels (List[int]): A list of the currently selected panels. + selected_panels (List[int]): A list of the currently selected panel IDs. can_save (bool): Whether the current revision can be saved. can_publish (bool): Whether the user has permission to publish the current revision. can_export (bool): Whether the user has permission to export files from the current revision. + panel_selection (Union[Unset, List['PanelSelectionResponse']]): A list of the currently selected panel details, + including ID. """ selected_panels: List[int] can_save: bool can_publish: bool can_export: bool + panel_selection: Union[Unset, List["PanelSelectionResponse"]] = UNSET additional_properties: Dict[str, Any] = _attrs_field(init=False, factory=dict) def to_dict(self) -> Dict[str, Any]: @@ -28,6 +37,13 @@ def to_dict(self) -> Dict[str, Any]: can_save = self.can_save can_publish = self.can_publish can_export = self.can_export + panel_selection: Union[Unset, List[Dict[str, Any]]] = UNSET + if not isinstance(self.panel_selection, Unset): + panel_selection = [] + for panel_selection_item_data in self.panel_selection: + panel_selection_item = panel_selection_item_data.to_dict() + + panel_selection.append(panel_selection_item) field_dict: Dict[str, Any] = {} field_dict.update(self.additional_properties) @@ -39,11 +55,15 @@ def to_dict(self) -> Dict[str, Any]: "canExport": can_export, } ) + if panel_selection is not UNSET: + field_dict["panelSelection"] = panel_selection return field_dict @classmethod def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: + from ..models.panel_selection_response import PanelSelectionResponse + d = src_dict.copy() selected_panels = cast(List[int], d.pop("selectedPanels")) @@ -53,11 +73,21 @@ def from_dict(cls: Type[T], src_dict: Dict[str, Any]) -> T: can_export = d.pop("canExport") + panel_selection = [] + _panel_selection = d.pop("panelSelection", UNSET) + for panel_selection_item_data in _panel_selection or []: + panel_selection_item = PanelSelectionResponse.from_dict( + panel_selection_item_data + ) + + panel_selection.append(panel_selection_item) + revision_status_response = cls( selected_panels=selected_panels, can_save=can_save, can_publish=can_publish, can_export=can_export, + panel_selection=panel_selection, ) revision_status_response.additional_properties = d diff --git a/flixpy/flix/extension/types.py b/flixpy/flix/extension/types.py index c86dca7..04a40e6 100644 --- a/flixpy/flix/extension/types.py +++ b/flixpy/flix/extension/types.py @@ -18,6 +18,7 @@ SourceFilePreviewMode, SourceFileType, ) +from .extension_api.types import Unset __all__ = [ "ActionEvent", @@ -36,6 +37,7 @@ "OpenSourceFileEvent", "PanelBrowserStatus", "PanelRequestResponse", + "PanelSelection", "ProjectDetails", "ProjectEvent", "ProjectIds", @@ -46,6 +48,7 @@ "Status", "StatusEvent", "VersionEvent", + "VersionResponse", ] @@ -261,6 +264,22 @@ class RevisionStatus: can_publish: bool = False can_export: bool = False selected_panels: list[int] = dataclasses.field(default_factory=list) + panel_selection: list[PanelSelection] = dataclasses.field(default_factory=list) + + +@dataclasses.dataclass +class PanelSelection: + id: int + revision_id: int + index: int + + @classmethod + def from_dict(cls, data: models.PanelSelectionResponse) -> Self: + return cls( + id=data.id, + revision_id=data.revision_id, + index=data.index, + ) @dataclasses.dataclass @@ -285,6 +304,12 @@ def from_model(cls, data: models.StatusResponse) -> Self: can_publish=data.revision_status.can_publish, can_export=data.revision_status.can_export, selected_panels=data.revision_status.selected_panels, + panel_selection=[ + PanelSelection.from_dict(panel) + for panel in data.revision_status.panel_selection + ] + if not isinstance(data.revision_status.panel_selection, Unset) + else [], ), actions_in_progress=ActionsInProgress( is_saving=data.actions_in_progress.is_saving, @@ -385,3 +410,16 @@ def from_dict(cls, data: models.PanelRequestResponse) -> Self: message=data.message, action_id=data.action_id, ) + + +@dataclasses.dataclass +class VersionResponse: + flix_version: str + supported_api_versions: list[str] + + @classmethod + def from_model(cls, data: models.InfoResponse) -> Self: + return cls( + flix_version=data.flix_version, + supported_api_versions=data.supported_api_versions, + )