clan-app: Implement open_clan_folder api request

This commit is contained in:
Qubasa
2025-07-10 14:19:19 +07:00
parent 0a8c7d9e10
commit f8ecd4372e
3 changed files with 95 additions and 0 deletions

View File

@@ -9,6 +9,8 @@ gi.require_version("Gtk", "4.0")
from clan_lib.api import ApiError, ErrorDataClass, SuccessDataClass
from clan_lib.api.directory import FileRequest
from clan_lib.clan.check import check_clan_valid
from clan_lib.flake import Flake
from gi.repository import Gio, GLib, Gtk
gi.require_version("Gtk", "4.0")
@@ -22,6 +24,51 @@ def remove_none(_list: list) -> list:
RESULT: dict[str, SuccessDataClass[list[str] | None] | ErrorDataClass] = {}
def open_clan_folder(*, op_key: str) -> SuccessDataClass[Flake] | ErrorDataClass:
"""
Opens the clan folder using the GTK file dialog.
Returns the path to the clan folder or an error if it fails.
"""
file_request = FileRequest(
mode="select_folder",
title="Select Clan Folder",
initial_folder=str(Path.home()),
)
response = open_file(file_request, op_key=op_key)
if isinstance(response, ErrorDataClass):
return response
if not response.data or len(response.data) == 0:
return ErrorDataClass(
op_key=op_key,
status="error",
errors=[
ApiError(
message="No folder selected",
description="You must select a folder to open.",
location=["open_clan_folder"],
)
],
)
clan_folder = Flake(response.data[0])
if not check_clan_valid(clan_folder):
return ErrorDataClass(
op_key=op_key,
status="error",
errors=[
ApiError(
message="Invalid clan folder",
description=f"The selected folder '{clan_folder}' is not a valid clan folder.",
location=["open_clan_folder"],
)
],
)
return SuccessDataClass(op_key=op_key, data=clan_folder, status="success")
def open_file(
file_request: FileRequest, *, op_key: str
) -> SuccessDataClass[list[str] | None] | ErrorDataClass:

View File

@@ -3,6 +3,7 @@ from dataclasses import dataclass, field
from typing import Any, Literal
from clan_lib.cmd import RunOpts, run
from clan_lib.flake import Flake
from clan_lib.nix import nix_shell
from . import API
@@ -38,6 +39,16 @@ def open_file(file_request: FileRequest) -> list[str] | None:
raise NotImplementedError(msg)
@API.register_abstract
def open_clan_folder() -> Flake:
"""
Abstract api method to open the clan folder.
It must return the path to the clan folder.
"""
msg = "open_clan_folder() is not implemented"
raise NotImplementedError(msg)
@dataclass
class BlkInfo:
name: str

View File

@@ -0,0 +1,37 @@
import logging
from clan_lib.api import API
from clan_lib.errors import ClanError
from clan_lib.flake import Flake
log = logging.getLogger(__name__)
@API.register
def check_clan_valid(flake: Flake) -> bool:
"""Check if a clan is valid by verifying if it has the clanInternals attribute.
Args:
flake: The Flake instance representing the clan.
Returns:
bool: True if the clan exists, False otherwise.
"""
try:
flake.prefetch()
except ClanError as e:
msg = f"Flake {flake} is not valid: {e}"
log.info(msg)
return False
if flake.is_local and not flake.path.exists():
msg = f"Path {flake} does not exist"
log.info(msg)
return False
try:
flake.select("clanInternals.inventoryClass.directory")
except ClanError as e:
msg = f"Flake {flake} is not a valid clan directory: {e}"
log.info(msg)
return False
return True