FixMediaDriver.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <?php
  2. namespace App\Console\Commands;
  3. use Illuminate\Console\Command;
  4. use Illuminate\Support\Facades\Storage;
  5. use App\Media;
  6. use League\Flysystem\MountManager;
  7. use App\Jobs\ImageOptimizePipeline\ImageOptimize;
  8. use App\Jobs\MediaPipeline\MediaFixLocalFilesystemCleanupPipeline;
  9. class FixMediaDriver extends Command
  10. {
  11. /**
  12. * The name and signature of the console command.
  13. *
  14. * @var string
  15. */
  16. protected $signature = 'media:fix-nonlocal-driver';
  17. /**
  18. * The console command description.
  19. *
  20. * @var string
  21. */
  22. protected $description = 'Fix filesystem when FILESYSTEM_DRIVER not set to local';
  23. /**
  24. * Execute the console command.
  25. *
  26. * @return int
  27. */
  28. public function handle()
  29. {
  30. if(config('filesystems.default') !== 'local') {
  31. $this->error('Invalid default filesystem, set FILESYSTEM_DRIVER=local to proceed');
  32. return Command::SUCCESS;
  33. }
  34. if((bool) config_cache('pixelfed.cloud_storage') == false) {
  35. $this->error('Cloud storage not enabled, exiting...');
  36. return Command::SUCCESS;
  37. }
  38. $this->info(' ____ _ ______ __ ');
  39. $this->info(' / __ \(_) _____ / / __/__ ____/ / ');
  40. $this->info(' / /_/ / / |/_/ _ \/ / /_/ _ \/ __ / ');
  41. $this->info(' / ____/ /> </ __/ / __/ __/ /_/ / ');
  42. $this->info(' /_/ /_/_/|_|\___/_/_/ \___/\__,_/ ');
  43. $this->info(' ');
  44. $this->info(' Media Filesystem Fix');
  45. $this->info(' =====================');
  46. $this->info(' Fix media that was created when FILESYSTEM_DRIVER=local');
  47. $this->info(' was not properly set. This command will fix media urls');
  48. $this->info(' and optionally optimize/generate thumbnails when applicable,');
  49. $this->info(' clean up temporary local media files and clear the app cache');
  50. $this->info(' to fix media paths/urls.');
  51. $this->info(' ');
  52. $this->error(' Remember, FILESYSTEM_DRIVER=local must remain set or you will break things!');
  53. if(!$this->confirm('Are you sure you want to perform this command?')) {
  54. $this->info('Exiting...');
  55. return Command::SUCCESS;
  56. }
  57. $optimize = $this->choice(
  58. 'Do you want to optimize media and generate thumbnails? This will store s3 locally and re-upload optimized versions.',
  59. ['no', 'yes'],
  60. 1
  61. );
  62. $cloud = Storage::disk(config('filesystems.cloud'));
  63. $mountManager = new MountManager([
  64. 's3' => $cloud->getDriver(),
  65. 'local' => Storage::disk('local')->getDriver(),
  66. ]);
  67. $this->info('Fixing media, this may take a while...');
  68. $this->line(' ');
  69. $bar = $this->output->createProgressBar(Media::whereNotNull('status_id')->whereNull('cdn_url')->count());
  70. $bar->start();
  71. foreach(Media::whereNotNull('status_id')->whereNull('cdn_url')->lazyById(20) as $media) {
  72. if($cloud->exists($media->media_path)) {
  73. if($optimize === 'yes') {
  74. $mountManager->copy(
  75. 's3://' . $media->media_path,
  76. 'local://' . $media->media_path
  77. );
  78. sleep(1);
  79. if(empty($media->original_sha256)) {
  80. $hash = \hash_file('sha256', Storage::disk('local')->path($media->media_path));
  81. $media->original_sha256 = $hash;
  82. $media->save();
  83. sleep(1);
  84. }
  85. if(
  86. $media->mime &&
  87. in_array($media->mime, [
  88. 'image/jpeg',
  89. 'image/png',
  90. 'image/webp'
  91. ])
  92. ) {
  93. ImageOptimize::dispatch($media);
  94. sleep(3);
  95. }
  96. } else {
  97. $media->cdn_url = $cloud->url($media->media_path);
  98. $media->save();
  99. }
  100. }
  101. $bar->advance();
  102. }
  103. $bar->finish();
  104. $this->line(' ');
  105. $this->line(' ');
  106. $this->callSilently('cache:clear');
  107. $this->info('Successfully fixed media paths and cleared cached!');
  108. if($optimize === 'yes') {
  109. MediaFixLocalFilesystemCleanupPipeline::dispatch()->delay(now()->addMinutes(15))->onQueue('default');
  110. $this->line(' ');
  111. $this->info('A cleanup job has been dispatched to delete media stored locally, it may take a few minutes to process!');
  112. }
  113. $this->line(' ');
  114. return Command::SUCCESS;
  115. }
  116. }