clan-app: Implement open_clan_folder api request
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
37
pkgs/clan-cli/clan_lib/clan/check.py
Normal file
37
pkgs/clan-cli/clan_lib/clan/check.py
Normal 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
|
||||
Reference in New Issue
Block a user