fixed migrations, changed settings to global settings, changed image list to have a "delete all" button instead of "create", fixed printing, added imagick for printing.

This commit is contained in:
2025-08-26 10:39:18 +02:00
parent 44dd0f2867
commit 9b1f6a479f
69 changed files with 17232 additions and 1263 deletions

View File

@@ -109,11 +109,22 @@ class ImageController extends Controller
public function styleChangeRequest(Request $request)
{
// Log the incoming request for debugging
\Illuminate\Support\Facades\Log::info('styleChangeRequest called', [
'image_id' => $request->image_id,
'style_id' => $request->style_id,
'all_params' => $request->all()
]);
// Same-origin check
$appUrl = config('app.url');
$referer = $request->headers->get('referer');
if ($referer && parse_url($referer, PHP_URL_HOST) !== parse_url($appUrl, PHP_URL_HOST)) {
\Illuminate\Support\Facades\Log::warning('Unauthorized styleChangeRequest', [
'referer' => $referer,
'app_url' => $appUrl
]);
return response()->json(['error' => 'Unauthorized: Request must originate from the same domain.'], 403);
}
@@ -127,7 +138,7 @@ class ImageController extends Controller
if ($request->style_id) {
$style = Style::with(['aiModel' => function ($query) {
$query->where('enabled', true)->with(['apiProviders' => function ($query) {
$query->where('enabled', true)->with(['primaryApiProvider', 'apiProviders' => function ($query) {
$query->where('enabled', true);
}]);
}])->find($request->style_id);
@@ -136,7 +147,7 @@ class ImageController extends Controller
$defaultStyleSetting = \App\Models\Setting::where('key', 'default_style_id')->first();
if ($defaultStyleSetting && $defaultStyleSetting->value) {
$style = Style::with(['aiModel' => function ($query) {
$query->where('enabled', true)->with(['apiProviders' => function ($query) {
$query->where('enabled', true)->with(['primaryApiProvider', 'apiProviders' => function ($query) {
$query->where('enabled', true);
}]);
}])->find($defaultStyleSetting->value);
@@ -144,14 +155,38 @@ class ImageController extends Controller
}
if (!$style || !$style->aiModel || $style->aiModel->apiProviders->isEmpty()) {
\Illuminate\Support\Facades\Log::warning('Style or provider not found', [
'style' => $style ? $style->toArray() : null,
'ai_model' => $style && $style->aiModel ? $style->aiModel->toArray() : null
]);
return response()->json(['error' => __('api.style_or_provider_not_found')], 404);
}
try {
$apiProvider = $style->aiModel->apiProviders->first(); // Get the first enabled API provider
// Use the primary API provider for this AI model if available
$apiProvider = $style->aiModel->primaryApiProvider;
if (!$apiProvider) {
// Fallback to the first enabled API provider from the many-to-many relationship
$apiProvider = $style->aiModel->apiProviders->where('enabled', true)->first();
}
if (!$apiProvider) {
// If no enabled provider found, try any provider
$apiProvider = $style->aiModel->apiProviders->first();
}
if (!$apiProvider) {
\Illuminate\Support\Facades\Log::error('No API provider found for style', [
'style_id' => $style->id,
'ai_model_id' => $style->aiModel->id
]);
return response()->json(['error' => __('api.style_or_provider_not_found')], 404);
}
\Illuminate\Support\Facades\Log::info('Selected API provider for style change', [
'api_provider_id' => $apiProvider->id,
'api_provider_name' => $apiProvider->name,
'plugin' => $apiProvider->plugin
]);
$plugin = PluginLoader::getPlugin($apiProvider->plugin, $apiProvider);
$result = $plugin->processImageStyleChange($image, $style);
@@ -162,12 +197,22 @@ class ImageController extends Controller
$image->save();
// Return the prompt_id for WebSocket tracking
\Illuminate\Support\Facades\Log::info('Style change request completed', [
'prompt_id' => $result['prompt_id'],
'image_uuid' => $image->uuid
]);
return response()->json([
'message' => 'Style change request sent.',
'prompt_id' => $result['prompt_id'],
'image_uuid' => $image->uuid, // Pass image UUID for frontend tracking
'plugin' => $apiProvider->plugin, // Pass plugin name for frontend handling
]);
} catch (\Exception $e) {
\Illuminate\Support\Facades\Log::error('Error in styleChangeRequest', [
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return response()->json(['error' => $e->getMessage()], 500);
}
}
@@ -230,8 +275,10 @@ class ImageController extends Controller
Log::info('fetchStyledImage called.', ['prompt_id' => $promptId]);
try {
// Find the image associated with the prompt_id, eagerly loading relationships
$image = Image::with(['style.aiModel.apiProviders' => function ($query) {
$query->where('enabled', true);
$image = Image::with(['style.aiModel' => function ($query) {
$query->with(['primaryApiProvider', 'apiProviders' => function ($query) {
$query->where('enabled', true);
}]);
}])->where('comfyui_prompt_id', $promptId)->first();
if (!$image) {
@@ -259,7 +306,16 @@ class ImageController extends Controller
Log::warning('fetchStyledImage: No enabled API Providers found for AI Model.', ['ai_model_id' => $style->aiModel->id]);
return response()->json(['error' => __('api.style_or_provider_not_found')], 404);
}
$apiProvider = $style->aiModel->apiProviders->first();
// Use the primary API provider for this AI model if available
$apiProvider = $style->aiModel->primaryApiProvider;
if (!$apiProvider) {
// Fallback to the first enabled API provider from the many-to-many relationship
$apiProvider = $style->aiModel->apiProviders->where('enabled', true)->first();
}
if (!$apiProvider) {
// If no enabled provider found, try any provider
$apiProvider = $style->aiModel->apiProviders->first();
}
Log::info('fetchStyledImage: API Provider found.', ['api_provider_id' => $apiProvider->id, 'api_provider_name' => $apiProvider->name]);
Log::info('Fetching base64 image from plugin.', ['prompt_id' => $promptId, 'api_provider' => $apiProvider->name]);
@@ -310,9 +366,85 @@ class ImageController extends Controller
}
}
public function getComfyUiUrl()
public function getComfyUiUrl(Request $request)
{
$apiProvider = ApiProvider::where('plugin', 'comfyui')->where('enabled', true)->first();
$styleId = $request->query('style_id');
$imageUuid = $request->query('image_uuid');
$apiProvider = null;
// If style_id is provided, get the API provider for that style
if ($styleId) {
$style = Style::with(['aiModel' => function ($query) {
$query->where('enabled', true)->with(['primaryApiProvider', 'apiProviders' => function ($query) {
$query->where('enabled', true);
}]);
}])->find($styleId);
if ($style && $style->aiModel) {
// Use the primary API provider for this AI model if available
$apiProvider = $style->aiModel->primaryApiProvider;
if (!$apiProvider) {
// Fallback to the first enabled API provider from the many-to-many relationship
$apiProvider = $style->aiModel->apiProviders->where('enabled', true)->first();
}
if (!$apiProvider) {
// If no enabled provider found, try any provider
$apiProvider = $style->aiModel->apiProviders->first();
}
}
}
// If image_uuid is provided, get the API provider for that image's style
elseif ($imageUuid) {
$image = Image::with(['style.aiModel' => function ($query) {
$query->with(['primaryApiProvider', 'apiProviders' => function ($query) {
$query->where('enabled', true);
}]);
}])->where('uuid', $imageUuid)->first();
if ($image && $image->style && $image->style->aiModel) {
// Use the primary API provider for this AI model if available
$apiProvider = $image->style->aiModel->primaryApiProvider;
if (!$apiProvider) {
// Fallback to the first enabled API provider from the many-to-many relationship
$apiProvider = $image->style->aiModel->apiProviders->where('enabled', true)->first();
}
if (!$apiProvider) {
// If no enabled provider found, try any provider
$apiProvider = $image->style->aiModel->apiProviders->first();
}
}
}
// Fallback to the old behavior if no style_id or image_uuid is provided
else {
// Try to get a default style if none is provided
$defaultStyleSetting = \App\Models\Setting::where('key', 'default_style_id')->first();
if ($defaultStyleSetting && $defaultStyleSetting->value) {
$style = Style::with(['aiModel' => function ($query) {
$query->where('enabled', true)->with(['primaryApiProvider', 'apiProviders' => function ($query) {
$query->where('enabled', true);
}]);
}])->find($defaultStyleSetting->value);
if ($style && $style->aiModel) {
// Use the primary API provider for this AI model if available
$apiProvider = $style->aiModel->primaryApiProvider;
if (!$apiProvider) {
// Fallback to the first enabled API provider from the many-to-many relationship
$apiProvider = $style->aiModel->apiProviders->where('enabled', true)->first();
}
if (!$apiProvider) {
// If no enabled provider found, try any provider
$apiProvider = $style->aiModel->apiProviders->first();
}
}
}
// If still no API provider, use the first available ComfyUI provider
if (!$apiProvider) {
$apiProvider = ApiProvider::where('plugin', 'ComfyUi')->where('enabled', true)->first();
}
}
if (!$apiProvider) {
return response()->json(['error' => 'No enabled ComfyUI API provider found.'], 404);

View File

@@ -4,12 +4,11 @@ namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;
use App\Services\PrinterService;
class PrintController extends Controller
{
public function printImage(Request $request)
public function printImage(Request $request, PrinterService $printerService)
{
$request->validate([
'image_path' => 'required|string',
@@ -18,36 +17,32 @@ class PrintController extends Controller
$imagePath = public_path(str_replace(url('/'), '', $request->input('image_path')));
$quantity = $request->input('quantity');
// Retrieve printer name from global settings using standard Eloquent
$printerName = \App\Models\Setting::where('key', 'selected_printer')->value('value');
if (!$printerName) {
Log::error("PrintController: Default printer name not found in settings.");
return response()->json(['error' => 'Default printer not configured.'], 500);
}
if (!$printerName) {
Log::error("PrintController: Default printer name not found in settings.");
return response()->json(['error' => 'Default printer not configured.'], 500);
}
if (!file_exists($imagePath)) {
Log::error("PrintController: Image file not found at {$imagePath}");
return response()->json(['error' => 'Image file not found.'], 404);
}
// IMPORTANT: Replace this command with one that works in your environment.
// Examples:
// Linux/macOS: $command = ['lpr', '-#', $quantity, $imagePath];
// Windows (assuming a shared printer named 'MyNetworkPrinter'):
// $command = ['print', '/d:\\MyNetworkPrinter', $imagePath];
// You might need to install additional software or configure your system
// to enable command-line printing.
// For a more robust solution, consider a dedicated print server application
// or a commercial print API.
$command = ['echo', "Simulating print of {$quantity} copies of {$imagePath}"]; // Placeholder
$printSuccess = $printerService->printImage($imagePath, $printerName, $quantity);
try {
$process = new Process($command);
$process->run();
if (!$process->isSuccessful()) {
throw new ProcessFailedException($process);
}
Log::info("PrintController: Successfully sent print command for {$imagePath} (x{$quantity})");
if ($printSuccess) {
Log::info("PrintController: Successfully sent print command for {$imagePath} (x{$quantity}) to {$printerName}");
return response()->json(['message' => 'Print command sent successfully.']);
} catch (ProcessFailedException $exception) {
Log::error("PrintController: Print command failed. Error: " . $exception->getMessage());
return response()->json(['error' => 'Failed to send print command.', 'details' => $exception->getMessage()], 500);
} else {
Log::error("PrintController: Failed to send print command for {$imagePath} (x{$quantity}) to {$printerName}");
return response()->json(['error' => 'Failed to send print command.'], 500);
}
}
}

View File

@@ -4,6 +4,7 @@ namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Inertia\Middleware;
use App\Models\Setting;
class HandleInertiaRequests extends Middleware
{
@@ -35,6 +36,7 @@ class HandleInertiaRequests extends Middleware
'user' => $request->user(),
],
'locale' => app()->getLocale(),
'settings' => Setting::all()->pluck('value', 'key'),
'translations' => function () use ($request) {
$currentLocale = app()->getLocale(); // Store current locale
$requestedLocale = $request->input('locale', $currentLocale);
@@ -47,8 +49,6 @@ class HandleInertiaRequests extends Middleware
// Add other translation files as needed
];
dd($lang); // <-- ADDED FOR DEBUGGING
app()->setLocale($currentLocale); // Revert to original locale
return $lang;
},