Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 168 additions & 0 deletions MULTI_URL_FEATURE_SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# Multi-URL Model Import Feature - Implementation Summary

## Overview
I've successfully added support for importing models from multiple URLs with fallback functionality. Users can now paste multiple URLs (one per line) and the system will attempt to download from each URL in sequence if previous attempts fail.

## Files Created

### 1. DirectUrlImportViewModel
**Location:** `/StabilityMatrix.Avalonia/ViewModels/CheckpointBrowser/DirectUrlImportViewModel.cs`

Features:
- Accepts multiple URLs (one per line) in a text input field
- Allows users to specify a model filename
- Provides a dropdown to select download location (Models/Checkpoints, Models/VAE, etc.)
- Validates input URLs and provides error messages
- Shows import status during download
- Automatically loads available model folders on initialization

Key Methods:
- `OnLoaded()`: Initializes available download locations
- `ImportCommand()`: Validates input and starts the download process using `IModelImportService.DoCustomImport()`
- `LoadAvailableDownloadLocations()`: Discovers model subdirectories

### 2. DirectUrlImportPage View
**Location:** `/StabilityMatrix.Avalonia/Views/DirectUrlImportPage.axaml` and `DirectUrlImportPage.axaml.cs`

UI Elements:
- **Title & Description**: Explains the feature
- **URLs Input Area**: Multi-line TextBox for entering download URLs
- **Filename Field**: Text input for specifying the model filename
- **Download Location Dropdown**: Select where to save the model
- **Status Indicator**: Shows current operation status
- **Start Download Button**: Triggers the import process
- **Help Section**: Tips for users about fallback URLs and file extensions

## Files Modified

### 1. CheckpointBrowserViewModel
**Location:** `/StabilityMatrix.Avalonia/ViewModels/CheckpointBrowserViewModel.cs`

Changes:
- Added `DirectUrlImportViewModel` parameter to constructor
- Added the new view model to the `Pages` list so it appears as a new tab in the Model Browser

Before:
```csharp
[civitAiBrowserViewModel, huggingFaceViewModel, openModelDbBrowserViewModel]
```

After:
```csharp
[civitAiBrowserViewModel, huggingFaceViewModel, openModelDbBrowserViewModel, directUrlImportViewModel]
```

### 2. ModelImportService
**Location:** `/StabilityMatrix.Avalonia/Services/ModelImportService.cs`

Changes:
- Modified `DoCustomImport()` method to support multiple URLs as fallback options
- First URL is used as primary, remaining URLs are stored as fallbacks
- When download fails, the system will automatically try the next URL in the sequence

Implementation:
```csharp
var uriList = modelUris.ToList();
var primaryUri = uriList.First();
var fallbackUris = uriList.Skip(1).ToList();

var download = trackedDownloadService.NewDownload(primaryUri, downloadPath);

if (fallbackUris.Count > 0)
{
download.FallbackUris = fallbackUris;
}
```

### 3. TrackedDownload
**Location:** `/StabilityMatrix.Core/Models/TrackedDownload.cs`

Changes:
- Added `FallbackUris` property to store alternative download URLs
- Added `currentUrlIndex` field to track which fallback URL is being used
- Added `CurrentDownloadUrl` computed property that returns the appropriate URL based on retry state
- Modified `StartDownloadTask()` to use `CurrentDownloadUrl` instead of `SourceUrl`
- Enhanced failure handling to try next fallback URL when download fails

Key Addition:
```csharp
public List<Uri>? FallbackUris { get; set; }

public Uri CurrentDownloadUrl =>
currentUrlIndex > 0 && FallbackUris is { Count: > 0 } && currentUrlIndex - 1 < FallbackUris.Count
? FallbackUris[currentUrlIndex - 1]
: SourceUrl;
```

## How It Works

### User Flow
1. User navigates to the new "Direct URL" tab in the Model Browser
2. User enters one or more URLs (each on a new line)
3. User specifies the filename for the model (e.g., `model.safetensors`)
4. User selects the download location from the dropdown
5. User clicks "Start Download"
6. System validates all inputs and initiates the download

### Download Flow
1. System creates a `TrackedDownload` with the first URL
2. Remaining URLs are stored as `FallbackUris`
3. Download starts with the primary URL
4. If download succeeds: File is saved to the specified location
5. If download fails:
- System checks for IO errors (retries up to 3 times with same URL)
- After 3 retries, if fallback URLs exist, attempts next URL
- Repeats until all URLs are exhausted or download succeeds
6. Success notification shown to user

## Features & Capabilities

✅ Multiple URL Support: Users can provide multiple URLs as fallback options
✅ Automatic Failover: System automatically tries next URL if previous fails
✅ Model Folder Selection: Choose where to save the model (by model type)
✅ Filename Customization: Specify any filename with proper extension
✅ Error Messages: Clear feedback on validation and import errors
✅ Status Updates: Real-time status of import operation
✅ Per-line URL Parsing: Robust parsing that handles various URL formats

## Testing Recommendations

### Basic Tests
- [ ] Enter single URL and verify download starts
- [ ] Enter multiple URLs and verify fallback tries if first fails
- [ ] Enter invalid URL and verify error message
- [ ] Leave filename empty and verify validation error
- [ ] Enter invalid URL format and verify error handling

### Advanced Tests
- [ ] Test with 3+ URLs to ensure all fallbacks are tried
- [ ] Test network timeout to ensure fallback URL is attempted
- [ ] Verify downloaded file is in the correct folder
- [ ] Test with different file extensions (.safetensors, .ckpt, .pth, etc.)

## Future Enhancements

Potential improvements for future versions:
1. Custom folder selection dialog (currently shows "Not yet implemented")
2. Preview image URL input for model metadata
3. Hash validation for downloaded files
4. URL validation before starting download (pre-check if URLs are accessible)
5. Queue multiple imports to run sequentially
6. Pause/Resume support for large downloads
7. Speed limit options for downloads

## Dependencies

Required services (injected via dependency injection):
- `IModelImportService`: Handles the actual import process
- `ISettingsManager`: Accesses settings like models directory paths
- `INotificationService`: Shows user notifications
- `ITrackedDownloadService`: Manages download tracking

## Notes

- The feature integrates seamlessly with the existing model browser architecture
- Uses the same download infrastructure as CivitAI and other model sources
- Follows the existing MVVM pattern used throughout the application
- All error handling includes user-friendly notifications
- The implementation is extensible for future model source integrations
17 changes: 13 additions & 4 deletions StabilityMatrix.Avalonia/Services/ModelImportService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -319,10 +319,19 @@ await notificationService.TryAsync(
cleanupFilePaths.Add(previewImageDownloadPath);
}

// Create tracked download
// todo: support multiple uris
var modelUri = modelUris.First();
var download = trackedDownloadService.NewDownload(modelUri, downloadPath);
// Create tracked download with first URL, storing others as fallbacks
// If download fails, the TrackedDownloadService will attempt to use fallback URLs
var uriList = modelUris.ToList();
var primaryUri = uriList.First();
var fallbackUris = uriList.Skip(1).ToList();

var download = trackedDownloadService.NewDownload(primaryUri, downloadPath);

// Store fallback URLs for retry attempts
if (fallbackUris.Count > 0)
{
download.FallbackUris = fallbackUris;
}

// Add hash info
// download.ExpectedHashSha256 = modelFile.Hashes.SHA256;
Expand Down
Loading
Loading