💬 Commit message: Update 2026-02-03 21:08:00, 3 files
This commit is contained in:
@@ -8,3 +8,8 @@ wheels/
|
|||||||
|
|
||||||
# Virtual environments
|
# Virtual environments
|
||||||
.venv
|
.venv
|
||||||
|
|
||||||
|
# Coverage
|
||||||
|
.coverage
|
||||||
|
htmlcov/
|
||||||
|
coverage.xml
|
||||||
|
|||||||
+61
-23
@@ -46,18 +46,24 @@ console = Console()
|
|||||||
# Configuration
|
# Configuration
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
|
|
||||||
# XDG Base Directory spec: ~/.config/tensors/config.toml
|
# XDG Base Directory spec
|
||||||
|
# Config: ~/.config/tensors/config.toml
|
||||||
|
# Data: ~/.local/share/tensors/models/, ~/.local/share/tensors/metadata/
|
||||||
CONFIG_DIR = Path(os.environ.get("XDG_CONFIG_HOME", Path.home() / ".config")) / "tensors"
|
CONFIG_DIR = Path(os.environ.get("XDG_CONFIG_HOME", Path.home() / ".config")) / "tensors"
|
||||||
CONFIG_FILE = CONFIG_DIR / "config.toml"
|
CONFIG_FILE = CONFIG_DIR / "config.toml"
|
||||||
|
|
||||||
|
DATA_DIR = Path(os.environ.get("XDG_DATA_HOME", Path.home() / ".local" / "share")) / "tensors"
|
||||||
|
MODELS_DIR = DATA_DIR / "models"
|
||||||
|
METADATA_DIR = DATA_DIR / "metadata"
|
||||||
|
|
||||||
# Legacy config for migration
|
# Legacy config for migration
|
||||||
LEGACY_RC_FILE = Path.home() / ".sftrc"
|
LEGACY_RC_FILE = Path.home() / ".sftrc"
|
||||||
|
|
||||||
# Default download paths by model type
|
# Default download paths by model type
|
||||||
DEFAULT_PATHS: dict[str, Path] = {
|
DEFAULT_PATHS: dict[str, Path] = {
|
||||||
"Checkpoint": Path.home() / ".xm" / "models" / "checkpoints",
|
"Checkpoint": MODELS_DIR / "checkpoints",
|
||||||
"LORA": Path.home() / ".xm" / "models" / "loras",
|
"LORA": MODELS_DIR / "loras",
|
||||||
"LoCon": Path.home() / ".xm" / "models" / "loras",
|
"LoCon": MODELS_DIR / "loras",
|
||||||
}
|
}
|
||||||
|
|
||||||
CIVITAI_API_BASE = "https://civitai.com/api/v1"
|
CIVITAI_API_BASE = "https://civitai.com/api/v1"
|
||||||
@@ -72,30 +78,62 @@ CIVITAI_DOWNLOAD_BASE = "https://civitai.com/api/download/models"
|
|||||||
class ModelType(str, Enum):
|
class ModelType(str, Enum):
|
||||||
"""CivitAI model types."""
|
"""CivitAI model types."""
|
||||||
|
|
||||||
checkpoint = "Checkpoint"
|
checkpoint = "checkpoint"
|
||||||
lora = "LORA"
|
lora = "lora"
|
||||||
embedding = "TextualInversion"
|
embedding = "embedding"
|
||||||
vae = "VAE"
|
vae = "vae"
|
||||||
controlnet = "Controlnet"
|
controlnet = "controlnet"
|
||||||
locon = "LoCon"
|
locon = "locon"
|
||||||
|
|
||||||
|
def to_api(self) -> str:
|
||||||
|
"""Convert to CivitAI API value."""
|
||||||
|
mapping = {
|
||||||
|
"checkpoint": "Checkpoint",
|
||||||
|
"lora": "LORA",
|
||||||
|
"embedding": "TextualInversion",
|
||||||
|
"vae": "VAE",
|
||||||
|
"controlnet": "Controlnet",
|
||||||
|
"locon": "LoCon",
|
||||||
|
}
|
||||||
|
return mapping[self.value]
|
||||||
|
|
||||||
|
|
||||||
class BaseModel(str, Enum):
|
class BaseModel(str, Enum):
|
||||||
"""Common base models."""
|
"""Common base models."""
|
||||||
|
|
||||||
sd15 = "SD 1.5"
|
sd15 = "sd15"
|
||||||
sdxl = "SDXL 1.0"
|
sdxl = "sdxl"
|
||||||
pony = "Pony"
|
pony = "pony"
|
||||||
flux = "Flux.1 D"
|
flux = "flux"
|
||||||
illustrious = "Illustrious"
|
illustrious = "illustrious"
|
||||||
|
|
||||||
|
def to_api(self) -> str:
|
||||||
|
"""Convert to CivitAI API value."""
|
||||||
|
mapping = {
|
||||||
|
"sd15": "SD 1.5",
|
||||||
|
"sdxl": "SDXL 1.0",
|
||||||
|
"pony": "Pony",
|
||||||
|
"flux": "Flux.1 D",
|
||||||
|
"illustrious": "Illustrious",
|
||||||
|
}
|
||||||
|
return mapping[self.value]
|
||||||
|
|
||||||
|
|
||||||
class SortOrder(str, Enum):
|
class SortOrder(str, Enum):
|
||||||
"""Sort options for search."""
|
"""Sort options for search."""
|
||||||
|
|
||||||
downloads = "Most Downloaded"
|
downloads = "downloads"
|
||||||
rating = "Highest Rated"
|
rating = "rating"
|
||||||
newest = "Newest"
|
newest = "newest"
|
||||||
|
|
||||||
|
def to_api(self) -> str:
|
||||||
|
"""Convert to CivitAI API value."""
|
||||||
|
mapping = {
|
||||||
|
"downloads": "Most Downloaded",
|
||||||
|
"rating": "Highest Rated",
|
||||||
|
"newest": "Newest",
|
||||||
|
}
|
||||||
|
return mapping[self.value]
|
||||||
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
@@ -345,12 +383,12 @@ def search_civitai(
|
|||||||
params["query"] = query
|
params["query"] = query
|
||||||
|
|
||||||
if model_type:
|
if model_type:
|
||||||
params["types"] = model_type.value
|
params["types"] = model_type.to_api()
|
||||||
|
|
||||||
if base_model:
|
if base_model:
|
||||||
params["baseModels"] = base_model.value
|
params["baseModels"] = base_model.to_api()
|
||||||
|
|
||||||
params["sort"] = sort.value
|
params["sort"] = sort.to_api()
|
||||||
|
|
||||||
# Request more if we need client-side filtering
|
# Request more if we need client-side filtering
|
||||||
if query and has_filters:
|
if query and has_filters:
|
||||||
@@ -760,8 +798,8 @@ def info(
|
|||||||
raise typer.Exit(1)
|
raise typer.Exit(1)
|
||||||
|
|
||||||
base_name = get_base_name(file_path)
|
base_name = get_base_name(file_path)
|
||||||
json_path = output_dir / f"{base_name}-xm.json"
|
json_path = output_dir / f"{base_name}.json"
|
||||||
sha_path = output_dir / f"{base_name}-xm.sha256"
|
sha_path = output_dir / f"{base_name}.sha256"
|
||||||
|
|
||||||
output = {
|
output = {
|
||||||
"file": str(file_path),
|
"file": str(file_path),
|
||||||
|
|||||||
Reference in New Issue
Block a user