diff --git a/README.md b/README.md index d446ea6..e98a45e 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ A curated list of plugins for the [Pelican Panel](https://pelican.dev). Feel fre - [Legal Pages](/legal-pages) - Adds legal pages (Imprint, Privacy Policy, ToS) to the panel - [MCLogs Uploader](/mclogs-uploader) - Upload console logs to mclo.gs - [Minecraft Modrinth](/minecraft-modrinth) - Download Minecraft mods & plugins from Modrinth +- [PasteFox Share](/pastefox-share) - Share console logs via pastefox.com - [Player Counter](/player-counter) - Show connected players count for game servers - [Register](/register) - Enable user self-registration on all panels - [Robo Avatars](/robo-avatars) - Adds RoboHash as avatar provider diff --git a/pastefox-share/README.md b/pastefox-share/README.md new file mode 100644 index 0000000..2ce676e --- /dev/null +++ b/pastefox-share/README.md @@ -0,0 +1,42 @@ +# PasteFox Share (by FlexKleks) + +Share console logs via [pastefox.com](https://pastefox.com) with one click. + +## Features + +- One-click log sharing from server console +- Optional API key for extended features (without API key, pastes expire after 7 days) +- Configurable visibility (PUBLIC/PRIVATE - requires API key) +- Visual effects (Matrix, Confetti, Glitch, etc.) +- Theme selection (Light/Dark) +- Password protection support +- Fetches up to 5000 log lines + +## Configuration + +1. Go to **Admin → Plugins** +2. Find **PasteFox Share** and click the **Settings** (gear icon) button +3. Configure the following settings: + +| Setting | Description | +|------------|----------------------------------------------------| +| API Key | Optional - Get from https://pastefox.com/dashboard | +| Visibility | PUBLIC or PRIVATE (requires API key) | +| Effect | Visual effect for the paste | +| Theme | Light or Dark theme | +| Password | Optional password protection | + +### Without API Key +- Pastes expire after 7 days +- Always public visibility + +### With API Key +- No expiration limit +- Private pastes available +- Password protection + +## Usage + +1. Open a server console +2. Click the **"Share Logs"** button in the header +3. Copy the generated link from the notification diff --git a/pastefox-share/config/pastefox-share.php b/pastefox-share/config/pastefox-share.php new file mode 100644 index 0000000..9a6094a --- /dev/null +++ b/pastefox-share/config/pastefox-share.php @@ -0,0 +1,9 @@ + env('PASTEFOX_API_KEY'), + 'visibility' => env('PASTEFOX_VISIBILITY', 'PUBLIC'), + 'effect' => env('PASTEFOX_EFFECT', 'NONE'), + 'theme' => env('PASTEFOX_THEME', 'dark'), + 'password' => env('PASTEFOX_PASSWORD'), +]; diff --git a/pastefox-share/lang/en/messages.php b/pastefox-share/lang/en/messages.php new file mode 100644 index 0000000..a52db8e --- /dev/null +++ b/pastefox-share/lang/en/messages.php @@ -0,0 +1,40 @@ + 'Share Logs', + 'share_file' => 'Share', + 'uploaded' => 'Logs uploaded to PasteFox', + 'file_uploaded' => 'File uploaded to PasteFox', + 'upload_failed' => 'Upload failed', + 'api_key_missing' => 'PasteFox API key not configured. Add it in the plugin settings.', + 'expires_7_days' => '⚠️ Without API key, paste expires in 7 days', + + // Settings + 'settings_saved' => 'Settings saved', + 'section_api' => 'API Configuration', + 'section_api_description' => 'Without API key, pastes expire after 7 days and are always public.', + 'section_paste' => 'Paste Settings', + 'api_key' => 'API Key', + 'api_key_helper' => 'Optional - Get your API key from https://pastefox.com/dashboard', + 'visibility' => 'Visibility', + 'visibility_public' => 'Public', + 'visibility_private' => 'Private (requires API key)', + 'visibility_helper' => 'Private pastes require an API key', + 'effect' => 'Visual Effect', + 'effect_none' => 'None', + 'effect_matrix' => 'Matrix Rain', + 'effect_glitch' => 'Glitch', + 'effect_confetti' => 'Confetti', + 'effect_scratch' => 'Scratch Card', + 'effect_puzzle' => 'Puzzle Reveal', + 'effect_slots' => 'Slot Machine', + 'effect_shake' => 'Shake', + 'effect_fireworks' => 'Fireworks', + 'effect_typewriter' => 'Typewriter', + 'effect_blur' => 'Blur Reveal', + 'theme' => 'Theme', + 'theme_dark' => 'Dark', + 'theme_light' => 'Light', + 'password' => 'Password Protection', + 'password_helper' => 'Optional - 4-100 characters', +]; diff --git a/pastefox-share/plugin.json b/pastefox-share/plugin.json new file mode 100644 index 0000000..bddec9d --- /dev/null +++ b/pastefox-share/plugin.json @@ -0,0 +1,15 @@ +{ + "id": "pastefox-share", + "name": "PasteFox Share", + "author": "FlexKleks", + "version": "1.0.0", + "description": "Share console logs via pastefox.com", + "category": "plugin", + "url": "https://github.com/pelican-dev/plugins/tree/main/pastefox-share", + "update_url": null, + "namespace": "FlexKleks\\PasteFoxShare", + "class": "PasteFoxSharePlugin", + "panels": ["admin", "server"], + "panel_version": null, + "composer_packages": null +} diff --git a/pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php b/pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php new file mode 100644 index 0000000..a26f5a1 --- /dev/null +++ b/pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php @@ -0,0 +1,115 @@ +hidden(function () { + /** @var Server $server */ + $server = Filament::getTenant(); + + return $server->retrieveStatus()->isOffline(); + }); + + $this->label(fn () => trans('pastefox-share::messages.share_logs')); + + $this->icon('tabler-share'); + + $this->color('primary'); + + $this->size(Size::ExtraLarge); + + $this->action(function () { + /** @var Server $server */ + $server = Filament::getTenant(); + + try { + $logs = Http::daemon($server->node) + ->get("/api/servers/{$server->uuid}/logs", [ + 'size' => 5000, + ]) + ->throw() + ->json('data'); + + $logs = is_array($logs) ? implode(PHP_EOL, $logs) : $logs; + + $apiKey = config('pastefox-share.api_key'); + $hasApiKey = filled($apiKey); + + $headers = ['Content-Type' => 'application/json']; + + $payload = [ + 'content' => $logs, + 'title' => 'Console Logs: ' . $server->name . ' - ' . now()->format('Y-m-d H:i:s'), + 'language' => 'log', + 'effect' => config('pastefox-share.effect'), + 'theme' => config('pastefox-share.theme'), + ]; + + if ($hasApiKey) { + $headers['X-API-Key'] = $apiKey; + $payload['visibility'] = config('pastefox-share.visibility'); + + $password = config('pastefox-share.password'); + if (filled($password)) { + $payload['password'] = $password; + } + } + + $response = Http::withHeaders($headers) + ->post('https://pastefox.com/api/pastes', $payload) + ->timeout(30) + ->connectTimeout(5) + ->throw() + ->json(); + + if ($response['success']) { + $url = 'https://pastefox.com/'.$response['data']['slug']; + + $body = $url; + if (!$hasApiKey) { + $body .= "\n".trans('pastefox-share::messages.expires_7_days'); + } + + Notification::make() + ->title(trans('pastefox-share::messages.uploaded')) + ->body($body) + ->persistent() + ->success() + ->send(); + } else { + Notification::make() + ->title(trans('pastefox-share::messages.upload_failed')) + ->body($response['error'] ?? 'Unknown error') + ->danger() + ->send(); + } + } catch (Exception $exception) { + report($exception); + + Notification::make() + ->title(trans('pastefox-share::messages.upload_failed')) + ->body($exception->getMessage()) + ->danger() + ->send(); + } + }); + } +} diff --git a/pastefox-share/src/PasteFoxSharePlugin.php b/pastefox-share/src/PasteFoxSharePlugin.php new file mode 100644 index 0000000..0941d02 --- /dev/null +++ b/pastefox-share/src/PasteFoxSharePlugin.php @@ -0,0 +1,104 @@ +description(trans('pastefox-share::messages.section_api_description')) + ->schema([ + TextInput::make('api_key') + ->label(trans('pastefox-share::messages.api_key')) + ->password() + ->revealable() + ->helperText(trans('pastefox-share::messages.api_key_helper')) + ->default(fn () => config('pastefox-share.api_key')), + ]), + + Section::make(trans('pastefox-share::messages.section_paste')) + ->schema([ + Select::make('visibility') + ->label(trans('pastefox-share::messages.visibility')) + ->options([ + 'PUBLIC' => trans('pastefox-share::messages.visibility_public'), + 'PRIVATE' => trans('pastefox-share::messages.visibility_private'), + ]) + ->default(fn () => config('pastefox-share.visibility', 'PUBLIC')) + ->helperText(trans('pastefox-share::messages.visibility_helper')), + + Select::make('effect') + ->label(trans('pastefox-share::messages.effect')) + ->options([ + 'NONE' => trans('pastefox-share::messages.effect_none'), + 'MATRIX' => trans('pastefox-share::messages.effect_matrix'), + 'GLITCH' => trans('pastefox-share::messages.effect_glitch'), + 'CONFETTI' => trans('pastefox-share::messages.effect_confetti'), + 'SCRATCH' => trans('pastefox-share::messages.effect_scratch'), + 'PUZZLE' => trans('pastefox-share::messages.effect_puzzle'), + 'SLOTS' => trans('pastefox-share::messages.effect_slots'), + 'SHAKE' => trans('pastefox-share::messages.effect_shake'), + 'FIREWORKS' => trans('pastefox-share::messages.effect_fireworks'), + 'TYPEWRITER' => trans('pastefox-share::messages.effect_typewriter'), + 'BLUR' => trans('pastefox-share::messages.effect_blur'), + ]) + ->default(fn () => config('pastefox-share.effect', 'NONE')), + + Select::make('theme') + ->label(trans('pastefox-share::messages.theme')) + ->options([ + 'dark' => trans('pastefox-share::messages.theme_dark'), + 'light' => trans('pastefox-share::messages.theme_light'), + ]) + ->default(fn () => config('pastefox-share.theme', 'dark')), + + TextInput::make('password') + ->label(trans('pastefox-share::messages.password')) + ->password() + ->revealable() + ->minLength(4) + ->maxLength(100) + ->helperText(trans('pastefox-share::messages.password_helper')) + ->default(fn () => config('pastefox-share.password')), + ]), + ]; + } + + public function saveSettings(array $data): void + { + $this->writeToEnvironment([ + 'PASTEFOX_API_KEY' => $data['api_key'] ?? '', + 'PASTEFOX_VISIBILITY' => $data['visibility'] ?? 'PUBLIC', + 'PASTEFOX_EFFECT' => $data['effect'] ?? 'NONE', + 'PASTEFOX_THEME' => $data['theme'] ?? 'dark', + 'PASTEFOX_PASSWORD' => $data['password'] ?? '', + ]); + + Notification::make() + ->title(trans('pastefox-share::messages.settings_saved')) + ->success() + ->send(); + } +} diff --git a/pastefox-share/src/Providers/PasteFoxSharePluginProvider.php b/pastefox-share/src/Providers/PasteFoxSharePluginProvider.php new file mode 100644 index 0000000..e7f28de --- /dev/null +++ b/pastefox-share/src/Providers/PasteFoxSharePluginProvider.php @@ -0,0 +1,18 @@ +