diff --git a/CHANGELOG.md b/CHANGELOG.md index 02ae77b6..48ed36a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Video WebP2P ([#4713](https://github.com/pixelfed/pixelfed/pull/4713)) ([0405ef12](https://github.com/pixelfed/pixelfed/commit/0405ef12)) - Added user:2fa command to easily disable 2FA for given account ([c6408fd7](https://github.com/pixelfed/pixelfed/commit/c6408fd7)) - Added `avatar:storage-deep-clean` command to dispatch remote avatar storage cleanup jobs ([c37b7cde](https://github.com/pixelfed/pixelfed/commit/c37b7cde)) +- Added S3 command to rewrite media urls ([5b3a5610](https://github.com/pixelfed/pixelfed/commit/5b3a5610)) ### Federation - Update Privacy Settings, add support for Mastodon `indexable` search flag ([fc24630e](https://github.com/pixelfed/pixelfed/commit/fc24630e)) diff --git a/app/Console/Commands/MediaCloudUrlRewrite.php b/app/Console/Commands/MediaCloudUrlRewrite.php new file mode 100644 index 00000000..54329f7c --- /dev/null +++ b/app/Console/Commands/MediaCloudUrlRewrite.php @@ -0,0 +1,140 @@ + 'The old S3 domain', + 'newDomain' => 'The new S3 domain' + ]; + } + /** + * The console command description. + * + * @var string + */ + protected $description = 'Rewrite S3 media urls from local users'; + + /** + * Execute the console command. + */ + public function handle() + { + $this->preflightCheck(); + $this->bootMessage(); + $this->confirmCloudUrl(); + } + + protected function preflightCheck() + { + if(config_cache('pixelfed.cloud_storage') != true) { + $this->info('Error: Cloud storage is not enabled!'); + $this->error('Aborting...'); + exit; + } + } + + protected function bootMessage() + { + $this->info(' ____ _ ______ __ '); + $this->info(' / __ \(_) _____ / / __/__ ____/ / '); + $this->info(' / /_/ / / |/_/ _ \/ / /_/ _ \/ __ / '); + $this->info(' / ____/ /> info(' /_/ /_/_/|_|\___/_/_/ \___/\__,_/ '); + $this->info(' '); + $this->info(' Media Cloud Url Rewrite Tool'); + $this->info(' ==='); + $this->info(' Old S3: ' . trim($this->argument('oldDomain'))); + $this->info(' New S3: ' . trim($this->argument('newDomain'))); + $this->info(' '); + } + + protected function confirmCloudUrl() + { + $disk = Storage::disk(config('filesystems.cloud'))->url('test'); + $domain = parse_url($disk, PHP_URL_HOST); + if(trim($this->argument('newDomain')) !== $domain) { + $this->error('Error: The new S3 domain you entered is not currently configured'); + exit; + } + + if(!$this->confirm('Confirm this is correct')) { + $this->error('Aborting...'); + exit; + } + + $this->updateUrls(); + } + + protected function updateUrls() + { + $this->info('Updating urls...'); + $oldDomain = trim($this->argument('oldDomain')); + $newDomain = trim($this->argument('newDomain')); + $disk = Storage::disk(config('filesystems.cloud')); + $count = Media::whereNotNull('cdn_url')->count(); + $bar = $this->output->createProgressBar($count); + $counter = 0; + $bar->start(); + foreach(Media::whereNotNull('cdn_url')->lazyById(1000, 'id') as $media) { + if(strncmp($media->media_path, 'http', 4) === 0) { + $bar->advance(); + continue; + } + $cdnHost = parse_url($media->cdn_url, PHP_URL_HOST); + if($oldDomain != $cdnHost || $newDomain == $cdnHost) { + $bar->advance(); + continue; + } + + $media->cdn_url = str_replace($oldDomain, $newDomain, $media->cdn_url); + + if($media->thumbnail_url != null) { + $thumbHost = parse_url($media->thumbnail_url, PHP_URL_HOST); + if($thumbHost == $oldDomain) { + $thumbUrl = $disk->url($media->thumbnail_path); + $media->thumbnail_url = $thumbUrl; + } + } + + if($media->optimized_url != null) { + $optiHost = parse_url($media->optimized_url, PHP_URL_HOST); + if($optiHost == $oldDomain) { + $optiUrl = str_replace($oldDomain, $newDomain, $media->optimized_url); + $media->optimized_url = $optiUrl; + } + } + + $media->save(); + $counter++; + $bar->advance(); + } + + $bar->finish(); + + $this->line(' '); + $this->info('Finished! Updated ' . $counter . ' total records!'); + $this->line(' '); + $this->info('Tip: Run `php artisan cache:clear` to purge cached urls'); + } +}