mirror of
https://github.com/pixelfed/pixelfed.git
synced 2025-02-24 07:00:46 +00:00
commit
aaee812b66
10 changed files with 214 additions and 18 deletions
127
app/Console/Commands/MediaReplaceDomainCommand.php
Normal file
127
app/Console/Commands/MediaReplaceDomainCommand.php
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Media;
|
||||||
|
use App\Services\MediaService;
|
||||||
|
use App\Services\StatusService;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class MediaReplaceDomainCommand extends Command
|
||||||
|
{
|
||||||
|
protected $signature = 'media:replacedomain {--original= : Original domain to replace} {--new= : New domain to use}';
|
||||||
|
|
||||||
|
protected $description = 'Replace CDN domain in media URLs and clear associated caches';
|
||||||
|
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$originalDomain = $this->option('original');
|
||||||
|
$newDomain = $this->option('new');
|
||||||
|
|
||||||
|
if (! $originalDomain || ! $newDomain) {
|
||||||
|
$this->error('Both --original and --new options are required');
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! str_starts_with($originalDomain, 'https://')) {
|
||||||
|
$this->error('Original domain must start with https://');
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! str_starts_with($newDomain, 'https://')) {
|
||||||
|
$this->error('New domain must start with https://');
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$originalDomain = rtrim($originalDomain, '/');
|
||||||
|
$newDomain = rtrim($newDomain, '/');
|
||||||
|
|
||||||
|
if (preg_match('/[^a-zA-Z0-9\-\._\/:]/', $originalDomain) ||
|
||||||
|
preg_match('/[^a-zA-Z0-9\-\._\/:]/', $newDomain)) {
|
||||||
|
$this->error('Domains contain invalid characters');
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sampleMedia = Media::where('cdn_url', 'LIKE', $originalDomain.'%')->first();
|
||||||
|
|
||||||
|
if (! $sampleMedia) {
|
||||||
|
$this->error('No media entries found with the specified domain.');
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sampleNewUrl = str_replace($originalDomain, $newDomain, $sampleMedia->cdn_url);
|
||||||
|
|
||||||
|
$this->info('Please verify this URL transformation:');
|
||||||
|
$this->newLine();
|
||||||
|
$this->info('Original URL:');
|
||||||
|
$this->line($sampleMedia->cdn_url);
|
||||||
|
$this->info('Will be changed to:');
|
||||||
|
$this->line($sampleNewUrl);
|
||||||
|
$this->newLine();
|
||||||
|
$this->info('Please verify in your browser that both URLs are accessible.');
|
||||||
|
|
||||||
|
if (! $this->confirm('Do you want to proceed with the replacement?')) {
|
||||||
|
$this->info('Operation cancelled.');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = Media::where('cdn_url', 'LIKE', $originalDomain.'%');
|
||||||
|
$count = $query->count();
|
||||||
|
|
||||||
|
$this->info("Found {$count} media entries to update.");
|
||||||
|
|
||||||
|
$bar = $this->output->createProgressBar($count);
|
||||||
|
$errors = [];
|
||||||
|
|
||||||
|
$query->chunkById(1000, function ($medias) use ($originalDomain, $newDomain, $bar, &$errors) {
|
||||||
|
foreach ($medias as $media) {
|
||||||
|
try {
|
||||||
|
if (! str_starts_with($media->cdn_url, 'https://')) {
|
||||||
|
$errors[] = "Media ID {$media->id} has invalid URL format: {$media->cdn_url}";
|
||||||
|
$bar->advance();
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
DB::transaction(function () use ($media, $originalDomain, $newDomain) {
|
||||||
|
$media->cdn_url = str_replace($originalDomain, $newDomain, $media->cdn_url);
|
||||||
|
$media->save();
|
||||||
|
|
||||||
|
if ($media->status_id) {
|
||||||
|
MediaService::del($media->status_id);
|
||||||
|
StatusService::del($media->status_id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$bar->advance();
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$errors[] = "Failed to update Media ID {$media->id}: {$e->getMessage()}";
|
||||||
|
$bar->advance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$bar->finish();
|
||||||
|
$this->newLine();
|
||||||
|
|
||||||
|
if (! empty($errors)) {
|
||||||
|
$this->newLine();
|
||||||
|
$this->warn('Completed with errors:');
|
||||||
|
foreach ($errors as $error) {
|
||||||
|
$this->error($error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info('Domain replacement completed successfully.');
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -74,19 +74,21 @@ class AppServiceProvider extends ServiceProvider
|
||||||
return $user->is_admin === 1;
|
return $user->is_admin === 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
Pulse::user(function ($user) {
|
if (config('pulse.enabled', false)) {
|
||||||
$acct = AccountService::get($user->profile_id, true);
|
Pulse::user(function ($user) {
|
||||||
|
$acct = AccountService::get($user->profile_id, true);
|
||||||
|
|
||||||
return $acct ? [
|
return $acct ? [
|
||||||
'name' => $acct['username'],
|
'name' => $acct['username'],
|
||||||
'extra' => $user->email,
|
'extra' => $user->email,
|
||||||
'avatar' => $acct['avatar'],
|
'avatar' => $acct['avatar'],
|
||||||
] : [
|
] : [
|
||||||
'name' => $user->username,
|
'name' => $user->username,
|
||||||
'extra' => 'DELETED',
|
'extra' => 'DELETED',
|
||||||
'avatar' => '/storage/avatars/default.jpg',
|
'avatar' => '/storage/avatars/default.jpg',
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
RateLimiter::for('app-signup', function (Request $request) {
|
RateLimiter::for('app-signup', function (Request $request) {
|
||||||
return Limit::perDay(10)->by($request->ip());
|
return Limit::perDay(10)->by($request->ip());
|
||||||
|
|
|
@ -274,6 +274,13 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li class="nav-item">
|
||||||
|
<router-link class="nav-link" to="/settings/home">
|
||||||
|
<span class="icon text-lighter"><i class="fa-cog"></i></span>
|
||||||
|
{{ $t('navmenu.settings') }}
|
||||||
|
</router-link>
|
||||||
|
</li>
|
||||||
|
|
||||||
<!-- <li class="nav-item">
|
<!-- <li class="nav-item">
|
||||||
<router-link class="nav-link d-flex justify-content-between align-items-center" to="/i/web/notifications">
|
<router-link class="nav-link d-flex justify-content-between align-items-center" to="/i/web/notifications">
|
||||||
<span>
|
<span>
|
||||||
|
|
|
@ -15,5 +15,5 @@ return [
|
||||||
|
|
||||||
'failed' => 'Los datos introducidos no son válidos.',
|
'failed' => 'Los datos introducidos no son válidos.',
|
||||||
'throttle' => 'Demasiados intentos de iniciar sesión. Por favor, inténtalo de nuevo en :seconds segundos.',
|
'throttle' => 'Demasiados intentos de iniciar sesión. Por favor, inténtalo de nuevo en :seconds segundos.',
|
||||||
|
'verifyYourEmailAddress' => ' - Verifica tu dirección de Correo',
|
||||||
];
|
];
|
||||||
|
|
|
@ -4,8 +4,8 @@ return [
|
||||||
|
|
||||||
'compose' => [
|
'compose' => [
|
||||||
'invalid' => [
|
'invalid' => [
|
||||||
'album' => 'Debe contener solo una foto o video, o multiples.',
|
'album' => 'Debe contener solo una foto o video, o múltiples.',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
28
resources/lang/es/helpcenter.php
Normal file
28
resources/lang/es/helpcenter.php
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
'helpcenter' => 'Centro de Ayuda',
|
||||||
|
'whatsnew' => 'Novedades',
|
||||||
|
|
||||||
|
'gettingStarted' => 'Primeros Pasos',
|
||||||
|
'sharingMedia' => 'Compartiendo Medios',
|
||||||
|
'profile' => 'Perfil',
|
||||||
|
'stories' => 'Historias',
|
||||||
|
'hashtags' => 'Hashtags',
|
||||||
|
'discover' => 'Descubre',
|
||||||
|
'directMessages' => 'Mensajes Directos',
|
||||||
|
'timelines' => 'Timelines',
|
||||||
|
'embed' => 'Embed',
|
||||||
|
|
||||||
|
'communityGuidelines' => 'Community Guidelines',
|
||||||
|
'whatIsTheFediverse' => '¿Qué es el fediverso?',
|
||||||
|
'controllingVisibility' => 'Controlando la Visibilidad',
|
||||||
|
'blockingAccounts' => 'Bloqueando Cuentas',
|
||||||
|
'safetyTips' => 'Tips de Seguridad',
|
||||||
|
'reportSomething' => 'Reportar Algo',
|
||||||
|
'dataPolicy' => 'Política sobre datos',
|
||||||
|
|
||||||
|
'taggingPeople' => 'Etiquetando Personas'
|
||||||
|
|
||||||
|
];
|
19
resources/lang/es/navmenu.php
Normal file
19
resources/lang/es/navmenu.php
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'search' => 'Buscar',
|
||||||
|
'home' => 'Inicio',
|
||||||
|
'local' => 'Local',
|
||||||
|
'network' => 'Network',
|
||||||
|
'discover' => 'Descubre',
|
||||||
|
'viewMyProfile' => 'Ver mi perfil',
|
||||||
|
'myProfile' => 'Mi Perfil',
|
||||||
|
'myTimeline' => 'Mi Timeline',
|
||||||
|
'publicTimeline' => 'Timeline público',
|
||||||
|
'remoteFollow' => 'Seguidor Remoto',
|
||||||
|
'settings' => 'Configuraciones',
|
||||||
|
'admin' => 'Admin',
|
||||||
|
'logout' => 'Cerrar Sesión',
|
||||||
|
'directMessages' => 'Mensajes Directos',
|
||||||
|
'composePost' => 'Crear Post',
|
||||||
|
];
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
'likedPhoto' => 'le gustó tu foto.',
|
'likedPhoto' => 'le gustó tu foto.',
|
||||||
'likedComment' => 'le gustó tu comentario.',
|
'likedComment' => 'le gustó tu comentario.',
|
||||||
'startedFollowingYou' => 'empezó a seguirte.',
|
'startedFollowingYou' => 'empezó a seguirte.',
|
||||||
'commented' => 'comentó tu foto.',
|
'commented' => 'comentó tu foto.',
|
||||||
'mentionedYou' => 'te menciono.',
|
'mentionedYou' => 'te mencionó.',
|
||||||
'shared' => 'compartir tu foto.',
|
'shared' => 'compartió tu foto.',
|
||||||
];
|
];
|
||||||
|
|
|
@ -4,5 +4,18 @@ return [
|
||||||
'emptyTimeline' => '¡Este usuario todavía no ha publicado nada!',
|
'emptyTimeline' => '¡Este usuario todavía no ha publicado nada!',
|
||||||
'emptyFollowers' => '¡Este usuario todavía no tiene seguidores!',
|
'emptyFollowers' => '¡Este usuario todavía no tiene seguidores!',
|
||||||
'emptyFollowing' => '¡Este usuario todavía no está siguiendo a nadie!',
|
'emptyFollowing' => '¡Este usuario todavía no está siguiendo a nadie!',
|
||||||
|
'emptySaved' => '¡No has guardado ninguna foto aún!',
|
||||||
'savedWarning' => 'Solamente tú puedes ver lo que has guardado',
|
'savedWarning' => 'Solamente tú puedes ver lo que has guardado',
|
||||||
|
'privateProfileWarning' => 'Esta cuenta es Privada',
|
||||||
|
'alreadyFollow' => '¿Ya sigues a :username?',
|
||||||
|
'loginToSeeProfile' => 'para ver sus fotos y videos.',
|
||||||
|
|
||||||
|
'status.disabled.header' => 'Perfil no disponible',
|
||||||
|
'status.disabled.body' => 'Disculpa, este perfil no está disponible en este momento. Por favor intenta nuevamente luego.',
|
||||||
|
|
||||||
|
'block.domain.max' => '¡Alcanzaste el limite máximo de dominios bloqueados! Tú solo puedes bloquear :max dominios por el momento. Pregúntale a tu administrador para ajustar este limite.',
|
||||||
|
|
||||||
|
'mutedAccounts' => 'Cuentas Silenciadas',
|
||||||
|
'blockedAccounts' => 'Cuentas Bloqueadas',
|
||||||
|
'blockedDomains' => 'Dominios Bloqueados',
|
||||||
];
|
];
|
||||||
|
|
0
resources/lang/es/settings.php
Normal file
0
resources/lang/es/settings.php
Normal file
Loading…
Reference in a new issue