Skip to content
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
80 changes: 80 additions & 0 deletions pastefox-share/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# PasteFox Share

A plugin for [Pelican Panel](https://pelican.dev) to 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
- Admin settings page in sidebar

## Installation

1. Download the latest release ZIP file from the [Releases](https://github.com/FlexKleks/PelicanPlugins/releases) page
2. Go to your Pelican Panel admin area
3. Navigate to **Admin → Plugins**
4. Click **"Import file"**
5. Select the downloaded ZIP file
6. Click **"Import"**
Comment thread
FlexKleks marked this conversation as resolved.
Outdated

### Clear Cache

```bash
php artisan optimize:clear
```
Comment thread
FlexKleks marked this conversation as resolved.
Outdated

## 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 |
Comment thread
FlexKleks marked this conversation as resolved.
Outdated
| 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
- Basic features only

### With API Key
- No expiration limit
- Private pastes available
- Password protection
- Paste linked to your account

## Usage

1. Open a server console
2. Click the **"Share Logs"** button in the header
3. Copy the generated link from the notification

## Coming Soon

- File sharing
- Custom domains
- Folders
- Syntax highlighting themes

## Author

Created by [FlexKleks](https://github.com/FlexKleks)

## Support

- [GitHub Issues](https://github.com/FlexKleks/PelicanPlugins/issues)
Comment thread
FlexKleks marked this conversation as resolved.
Outdated
- [Pelican Discord](https://discord.gg/pelican-panel)

## License

MIT
Comment thread
FlexKleks marked this conversation as resolved.
Outdated
9 changes: 9 additions & 0 deletions pastefox-share/config/pastefox-share.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

return [
'api_key' => env('PASTEFOX_API_KEY'),
'visibility' => env('PASTEFOX_VISIBILITY', 'PUBLIC'),
'effect' => env('PASTEFOX_EFFECT', 'NONE'),
'theme' => env('PASTEFOX_THEME', 'dark'),
'password' => env('PASTEFOX_PASSWORD'),
];
11 changes: 11 additions & 0 deletions pastefox-share/lang/en/messages.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

return [
'share_logs' => 'Share Logs',
'share_file' => 'Share',
Comment thread
FlexKleks marked this conversation as resolved.
'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',
];
15 changes: 15 additions & 0 deletions pastefox-share/plugin.json
Original file line number Diff line number Diff line change
@@ -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/FlexKleks/PelicanPlugins",
Comment thread
FlexKleks marked this conversation as resolved.
Outdated
"update_url": null,
"namespace": "FlexKleks\\PasteFoxShare",
"class": "PasteFoxSharePlugin",
"panels": ["admin", "server"],
"panel_version": null,
"composer_packages": null
}
115 changes: 115 additions & 0 deletions pastefox-share/src/Filament/Components/Actions/UploadLogsAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php

namespace FlexKleks\PasteFoxShare\Filament\Components\Actions;

use App\Models\Server;
use Exception;
use Filament\Actions\Action;
use Filament\Facades\Filament;
use Filament\Notifications\Notification;
use Filament\Support\Enums\Size;
use Illuminate\Support\Facades\Http;

class UploadLogsAction extends Action
{
public static function getDefaultName(): ?string
{
return 'upload_logs_pastefox';
}

protected function setUp(): void
{
parent::setUp();

$this->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();
}
Comment thread
FlexKleks marked this conversation as resolved.
} catch (Exception $exception) {
report($exception);

Notification::make()
->title(trans('pastefox-share::messages.upload_failed'))
->body($exception->getMessage())
->danger()
->send();
}
});
}
}
Comment thread
FlexKleks marked this conversation as resolved.
104 changes: 104 additions & 0 deletions pastefox-share/src/PasteFoxSharePlugin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php

namespace FlexKleks\PasteFoxShare;

use App\Contracts\Plugins\HasPluginSettings;
use App\Traits\EnvironmentWriterTrait;
Comment thread
FlexKleks marked this conversation as resolved.
use Filament\Contracts\Plugin;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Notifications\Notification;
use Filament\Panel;
use Filament\Schemas\Components\Section;

class PasteFoxSharePlugin implements HasPluginSettings, Plugin
{
use EnvironmentWriterTrait;

public function getId(): string
{
return 'pastefox-share';
}

public function register(Panel $panel): void {}

public function boot(Panel $panel): void {}

public function getSettingsForm(): array
{
return [
Section::make('API Configuration')
->description('Without API key, pastes expire after 7 days and are always public.')
->schema([
TextInput::make('api_key')
->label('API Key')
->password()
->revealable()
->helperText('Optional - Get your API key from https://pastefox.com/dashboard')
->default(fn () => config('pastefox-share.api_key')),
]),

Section::make('Paste Settings')
->schema([
Select::make('visibility')
->label('Visibility')
->options([
'PUBLIC' => 'Public',
'PRIVATE' => 'Private (requires API key)',
])
->default(fn () => config('pastefox-share.visibility', 'PUBLIC'))
->helperText('Private pastes require an API key'),

Select::make('effect')
->label('Visual Effect')
->options([
'NONE' => 'None',
'MATRIX' => 'Matrix Rain',
'GLITCH' => 'Glitch',
'CONFETTI' => 'Confetti',
'SCRATCH' => 'Scratch Card',
'PUZZLE' => 'Puzzle Reveal',
'SLOTS' => 'Slot Machine',
'SHAKE' => 'Shake',
'FIREWORKS' => 'Fireworks',
'TYPEWRITER' => 'Typewriter',
'BLUR' => 'Blur Reveal',
])
->default(fn () => config('pastefox-share.effect', 'NONE')),

Select::make('theme')
->label('Theme')
->options([
'dark' => 'Dark',
'light' => 'Light',
])
->default(fn () => config('pastefox-share.theme', 'dark')),

TextInput::make('password')
->label('Password Protection')
->password()
->revealable()
->minLength(4)
->maxLength(100)
->helperText('Optional - 4-100 characters')
->default(fn () => config('pastefox-share.password')),
Comment thread
FlexKleks marked this conversation as resolved.
Outdated
]),
];
}

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('Settings saved')
->success()
->send();
}
Comment thread
FlexKleks marked this conversation as resolved.
}
18 changes: 18 additions & 0 deletions pastefox-share/src/Providers/PasteFoxSharePluginProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace FlexKleks\PasteFoxShare\Providers;

use App\Enums\HeaderActionPosition;
use App\Filament\Server\Pages\Console;
use FlexKleks\PasteFoxShare\Filament\Components\Actions\UploadLogsAction;
use Illuminate\Support\ServiceProvider;

class PasteFoxSharePluginProvider extends ServiceProvider
{
public function register(): void
{
Console::registerCustomHeaderActions(HeaderActionPosition::Before, UploadLogsAction::make());
}

public function boot(): void {}
}