Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ npm i -g yarn
- [Billing](/billing) - Allows users to purchase servers via Stripe - **Proof of Concept - Do absolutely NOT use in production!**
- [Generic OIDC Providers](/generic-oidc-providers) - Create generic OIDC providers for authentication
- [Legal Pages](/legal-pages) - Adds legal pages (Imprint, Privacy Policy, ToS) to the panel
- [McLogCleaner](/mclogcleaner) - Delete old logs with ease
- [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
Expand Down
15 changes: 15 additions & 0 deletions mclogcleaner/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## McLogCleaner
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## McLogCleaner
# McLogCleaner (by JuggleGaming)


McLogCleaner automatically deletes all `.log.gz` files from the server’s `logs` folder.

> **Note:** `latest.yml` will always remain intact and is never deleted.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

### Usage
To use this plugin, add `mclogcleaner` as a feature to the egg you want to run it with.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### Usage
To use this plugin, add `mclogcleaner` as a feature to the egg you want to run it with.
## Setup
To use this plugin, add `mclogcleaner` as a _feature_ to the egg you want to run it with.


### Log Deletion Options
When you click **Delete logs**, a dropdown menu appears where you can choose the **minimum age (in days)** of log files to delete:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### Log Deletion Options
When you click **Delete logs**, a dropdown menu appears where you can choose the **minimum age (in days)** of log files to delete:
## Log Deletion Options
When you click **Delete logs**, a dropdown menu appears where you can choose the **minimum age (in days)** of log files to delete:

- Logs older than 7 days
- Logs older than 30 days
- All logs (regardless of age)
- A custom age in days
5 changes: 5 additions & 0 deletions mclogcleaner/config/logcleaner.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

return [
// Config values for LogCleaner
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove empty config.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

];
15 changes: 15 additions & 0 deletions mclogcleaner/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"id": "mclogcleaner",
"name": "McLogCleaner",
"author": "JuggleGaming",
"version": "1.1.0",
"description": "Clean your Minecraft-logs with ease",
"category": "plugin",
"url": "https://github.com/pelican-dev/plugins/tree/main/mclogcleaner",
"update_url": null,
"namespace": "JuggleGaming\\McLogCleaner",
"class": "McLogCleanerPlugin",
"panels": null,
"panel_version": null,
"composer_packages": null
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
27 changes: 27 additions & 0 deletions mclogcleaner/src/Enums/CheckEgg.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace JuggleGaming\McLogCleaner\Enums;

use App\Models\Server;

enum CheckEgg: string {
case Check = 'mclogcleaner';

public static function fromServer(Server $server): ?self
{
$server->loadMissing('egg');

$features = $server->egg->features ?? [];
Comment thread
Boy132 marked this conversation as resolved.
Outdated

if (in_array(self::Check->value, $features, true)) {
return self::Check;
}

return null;
}

public static function serverSupportsLogCleaner(Server $server): bool
{
return self::fromServer($server) !== null;
}
}
156 changes: 156 additions & 0 deletions mclogcleaner/src/Filament/Components/Actions/McLogCleanAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<?php
Comment thread
coderabbitai[bot] marked this conversation as resolved.

namespace JuggleGaming\McLogCleaner\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;
use JuggleGaming\McLogCleaner\Enums\CheckEgg;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Carbon\Carbon;

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

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

$this->hidden(function () {
$server = Filament::getTenant();
return !CheckEgg::serverSupportsLogCleaner($server);
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.

$this->label('Delete logs');
$this->icon('tabler-trash');
$this->color('danger');
$this->size(Size::ExtraLarge);

$this->requiresConfirmation()
->modalHeading('Delete logs')
->modalDescription('Choose which logs should be deleted.')
->modalSubmitActionLabel('Delete logs')
->form([
Select::make('mode')
->label('Delete logs')
->options([
7 => 'Older than 7 days',
30 => 'Older than 30 days',
-1 => 'Delete all logs',
'custom' => 'Custom (days)',
])
->default(7)
->required()
->reactive(),

TextInput::make('custom_days')
->label('Delete logs older than (days)')
->numeric()
->minValue(1)
->maxValue(365)
->placeholder('e.g. 14')
->required(fn ($get) => $get('mode') === 'custom')
->visible(fn ($get) => $get('mode') === 'custom'),
]);

$this->action(function (array $data) {
$server = Filament::getTenant();

$mode = $data['mode'];
if ($mode !== 'custom') {
$mode = (int) $mode;
}

if ($mode === 'custom') {
$days = max(1, (int) $data['custom_days']);
} elseif ($mode === -1) {
$days = 0;
} else {
$days = $mode;
}

try {
$files = Http::daemon($server->node)
->get("/api/servers/{$server->uuid}/files/list-directory", [
'directory' => 'logs',
])
->throw()
->json();

if (!is_array($files)) {
throw new Exception('Invalid log directory response.');
}

$threshold = now()->subDays($days)->startOfDay();

$logsToDelete = collect($files)
->filter(fn ($file) => str_ends_with($file['name'], '.log.gz'))
->filter(function ($file) use ($days, $threshold) {
if ($days === 0) {
return true;
}

$logDate = $this->extractLogDate($file['name']);

if (!$logDate) {
return false;
}

return $logDate->lessThan($threshold);
})
->pluck('name')
->map(fn ($name) => 'logs/' . $name)
->values()
->all();

if (empty($logsToDelete)) {
Notification::make()
->title('McLogCleaner')
->body('No logs matching your selection were found.')
->success()
->send();
return;
}

Http::daemon($server->node)
->post("/api/servers/{$server->uuid}/files/delete", [
'root' => '/',
'files' => $logsToDelete,
])
->throw();

Notification::make()
->title('Logfolder cleaned')
->body(count($logsToDelete) . ' files were deleted.')
->success()
->send();

} catch (\Throwable $e) {
report($e);

Notification::make()
->title('Cleanup failed.')
->body($e->getMessage())
->danger()
->send();
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
});
}

private function extractLogDate(string $filename): ?Carbon
{
if (preg_match('/(\d{4}-\d{2}-\d{2})/', $filename, $matches)) {
return Carbon::createFromFormat('Y-m-d', $matches[1])->startOfDay();
}
return null;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
18 changes: 18 additions & 0 deletions mclogcleaner/src/McLogCleanerPlugin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace JuggleGaming\McLogCleaner;

use Filament\Contracts\Plugin;
use Filament\Panel;

class McLogCleanerPlugin implements Plugin
{
public function getId(): string
{
return 'logcleaner';
}

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

public function boot(Panel $panel): void {}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}
18 changes: 18 additions & 0 deletions mclogcleaner/src/Providers/McLogCleanerPluginProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace JuggleGaming\McLogCleaner\Providers;

use Illuminate\Support\ServiceProvider;
use App\Enums\HeaderActionPosition;
use App\Filament\Server\Pages\Console;
use JuggleGaming\McLogCleaner\Filament\Components\Actions\McLogCleanAction;

class McLogCleanerPluginProvider extends ServiceProvider {

public function register(): void {
Console::registerCustomHeaderActions(HeaderActionPosition::Before, McLogCleanAction::make());
}

public function boot(): void {}

}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
Loading