diff --git a/app/Api/Plugins/RunwareAi.php b/app/Api/Plugins/RunwareAi.php
index 4031ca0..d5711b3 100644
--- a/app/Api/Plugins/RunwareAi.php
+++ b/app/Api/Plugins/RunwareAi.php
@@ -103,17 +103,34 @@ class RunwareAi implements ApiPluginInterface
try {
$response = Http::withHeaders([
- 'Authorization' => 'Bearer ' . $token,
+ 'Content-Type' => 'application/json',
'Accept' => 'application/json',
])->timeout(5)->post($apiUrl, [
[
- 'taskType' => 'ping',
+ 'taskType' => 'authentication',
+ 'apiKey' => $token,
]
]);
- return $response->successful();
+ $responseData = $response->json();
+
+ if ($response->successful() && isset($responseData['data']) && !isset($responseData['error'])) {
+ $this->logInfo('RunwareAI connection test successful: Authentication successful.', [
+ 'status' => $response->status(),
+ 'response' => $responseData,
+ ]);
+ return true;
+ } else {
+ $errorMessage = $responseData['error'] ?? 'Unknown error';
+ $this->logError('RunwareAI connection test failed: Authentication failed.', [
+ 'status' => $response->status(),
+ 'response' => $responseData,
+ 'error_message' => $errorMessage,
+ ]);
+ return false;
+ }
} catch (\Exception $e) {
- $this->logError('RunwareAI connection test failed.', ['error' => $e->getMessage()]);
+ $this->logError('RunwareAI connection test failed: Exception caught.', ['error' => $e->getMessage()]);
return false;
}
}
diff --git a/app/Filament/Resources/ApiProviderResource.php b/app/Filament/Resources/ApiProviderResource.php
index 65774f1..15024ca 100644
--- a/app/Filament/Resources/ApiProviderResource.php
+++ b/app/Filament/Resources/ApiProviderResource.php
@@ -26,6 +26,7 @@ use Filament\Notifications\Notification;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Log;
+use App\Api\Plugins\PluginLoader;
class ApiProviderResource extends Resource
{
@@ -90,67 +91,59 @@ class ApiProviderResource extends Resource
->action(function (array $data, Forms\Components\Component $component, \Livewire\Component $livewire) {
$formData = $component->getLivewire()->form->getState();
$apiUrl = str_replace('127.0.0.1', 'localhost', $formData['api_url'] ?? null);
- $plugin = $formData['plugin'] ?? null;
- $username = $formData['username'] ?? null;
- $password = $formData['password'] ?? null;
+ $pluginName = $formData['plugin'] ?? null;
$token = $formData['token'] ?? null;
+ if (!$pluginName) {
+ Notification::make()
+ ->title(__('filament.resource.api_provider.notification.connection_failed'))
+ ->body('Please select a plugin first.')
+ ->danger()
+ ->send();
+ $component->getLivewire()->dispatch('testConnectionFinished', result: 'failed');
+ return;
+ }
+
try {
- $http = Http::timeout(25);
+ // Create a dummy ApiProvider model for the test
+ $dummyApiProvider = new \App\Models\ApiProvider();
+ $dummyApiProvider->api_url = $apiUrl;
+ $dummyApiProvider->token = $token;
- if ($username && $password) {
- $http->withBasicAuth($username, $password);
- } elseif ($token) {
- $http->withToken($token);
- }
+ // Load the specific plugin using the PluginLoader
+ $pluginInstance = PluginLoader::getPlugin($pluginName, $dummyApiProvider);
- $response = $http->get($apiUrl);
+ // Call the testConnection method of the plugin
+ $testResult = $pluginInstance->testConnection([
+ 'api_url' => $apiUrl,
+ 'token' => $token,
+ 'username' => $formData['username'] ?? null,
+ 'password' => $formData['password'] ?? null,
+ ]);
- if ($response->successful()) {
- Log::info('External API connection successful.', [
- 'api_url' => $apiUrl,
- 'plugin' => $plugin,
- ]);
+ if ($testResult) {
Notification::make()
->title(__('filament.resource.api_provider.notification.connection_successful'))
->success()
->send();
$component->getLivewire()->dispatch('testConnectionFinished', result: 'success');
} else {
- Log::warning('External API connection failed: Non-successful response.', [
- 'api_url' => $apiUrl,
- 'plugin' => $plugin,
- 'status' => $response->status(),
- 'response_body' => $response->body(),
- ]);
Notification::make()
->title(__('filament.resource.api_provider.notification.connection_failed'))
- ->body($response->json('message', 'An unknown error occurred.'))
+ ->body('Plugin reported connection failed. Check logs for details.')
->danger()
->send();
$component->getLivewire()->dispatch('testConnectionFinished', result: 'failed');
}
- } catch (\Illuminate\Http\Client\RequestException $e) {
- Log::error('External API connection failed: Timeout or network error.', [
- 'api_url' => $apiUrl,
- 'plugin' => $plugin,
- 'error_message' => $e->getMessage(),
- ]);
- Notification::make()
- ->title(__('filament.resource.api_provider.notification.connection_failed'))
- ->body('Timeout or network error: ' . $e->getMessage())
- ->danger()
- ->send();
- $component->getLivewire()->dispatch('testConnectionFinished', result: 'failed');
} catch (\Exception $e) {
- Log::error('External API connection failed: An unexpected error occurred.', [
+ Log::error('Plugin test connection failed: An unexpected error occurred.', [
'api_url' => $apiUrl,
- 'plugin' => $plugin,
+ 'plugin' => $pluginName,
'error_message' => $e->getMessage(),
]);
Notification::make()
->title(__('filament.resource.api_provider.notification.connection_failed'))
- ->body('An unexpected error occurred: ' . $e->getMessage())
+ ->body('An unexpected error occurred during plugin test: ' . $e->getMessage())
->danger()
->send();
$component->getLivewire()->dispatch('testConnectionFinished', result: 'failed');
diff --git a/app/Http/Controllers/Api/StyleController.php b/app/Http/Controllers/Api/StyleController.php
index c038e1f..3b6fe71 100644
--- a/app/Http/Controllers/Api/StyleController.php
+++ b/app/Http/Controllers/Api/StyleController.php
@@ -35,4 +35,11 @@ class StyleController extends Controller
return response()->json(['interval' => $interval ? (int)$interval->value / 1000 : 5]);
}
+
+ public function getMaxNumberOfCopies()
+ {
+ $maxCopies = Setting::where('key', 'max_number_of_copies')->first();
+
+ return response()->json(['max_copies' => $maxCopies ? (int)$maxCopies->value : 10]); // Default to 10 if not set
+ }
}
\ No newline at end of file
diff --git a/app/Http/Controllers/PrintController.php b/app/Http/Controllers/PrintController.php
new file mode 100644
index 0000000..e62b963
--- /dev/null
+++ b/app/Http/Controllers/PrintController.php
@@ -0,0 +1,53 @@
+validate([
+ 'image_path' => 'required|string',
+ 'quantity' => 'required|integer|min:1',
+ ]);
+
+ $imagePath = public_path(str_replace(url('/'), '', $request->input('image_path')));
+ $quantity = $request->input('quantity');
+
+ 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
+
+ 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})");
+ 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);
+ }
+ }
+}
diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php
index a7bb293..490f2e2 100644
--- a/database/seeders/DatabaseSeeder.php
+++ b/database/seeders/DatabaseSeeder.php
@@ -14,7 +14,8 @@ class DatabaseSeeder extends Seeder
{
$this->call([
RoleSeeder::class,
- UserSeeder::class
+ UserSeeder::class,
+ MaxCopiesSettingSeeder::class,
]);
}
}
diff --git a/database/seeders/MaxCopiesSettingSeeder.php b/database/seeders/MaxCopiesSettingSeeder.php
new file mode 100644
index 0000000..4db30c3
--- /dev/null
+++ b/database/seeders/MaxCopiesSettingSeeder.php
@@ -0,0 +1,20 @@
+ 'max_number_of_copies'],
+ ['value' => 10] // Default value
+ );
+ }
+}
diff --git a/resources/js/Components/ImageContextMenu.vue b/resources/js/Components/ImageContextMenu.vue
index c76b731..1a515a6 100644
--- a/resources/js/Components/ImageContextMenu.vue
+++ b/resources/js/Components/ImageContextMenu.vue
@@ -5,28 +5,23 @@