123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- <?php
- namespace App\Console\Commands;
- use Illuminate\Console\Command;
- use App\Avatar;
- use App\Profile;
- use App\Jobs\AvatarPipeline\RemoteAvatarFetch;
- use App\Util\ActivityPub\Helpers;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Str;
- class AvatarSync extends Command
- {
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'avatars:sync';
- /**
- * The console command description.
- *
- * @var string
- */
- protected $description = 'Perform actions on avatars';
- public $found = 0;
- public $notFetched = 0;
- public $fixed = 0;
- /**
- * Create a new command instance.
- *
- * @return void
- */
- public function __construct()
- {
- parent::__construct();
- }
- /**
- * Execute the console command.
- *
- * @return int
- */
- public function handle()
- {
- $this->info('Welcome to the avatar sync manager');
- $actions = [
- 'Analyze',
- 'Full Analyze',
- 'Fetch - Fetch missing remote avatars',
- 'Fix - Fix remote accounts without avatar record',
- 'Sync - Store latest remote avatars',
- ];
- $name = $this->choice(
- 'Select an action',
- $actions,
- 0,
- 1,
- false
- );
- $this->info('Selected: ' . $name);
- switch($name) {
- case $actions[0]:
- $this->analyze();
- break;
- case $actions[1]:
- $this->fullAnalyze();
- break;
- case $actions[2]:
- $this->fetch();
- break;
- case $actions[3]:
- $this->fix();
- break;
- case $actions[4]:
- $this->sync();
- break;
- }
- return Command::SUCCESS;
- }
- protected function incr($name)
- {
- switch($name) {
- case 'found':
- $this->found = $this->found + 1;
- break;
- case 'notFetched':
- $this->notFetched = $this->notFetched + 1;
- break;
- case 'fixed':
- $this->fixed++;
- break;
- }
- }
- protected function analyze()
- {
- $count = Avatar::whereIsRemote(true)->whereNull('cdn_url')->count();
- $this->info('Found ' . $count . ' profiles with blank avatars.');
- $this->line(' ');
- $this->comment('We suggest running php artisan avatars:sync again and selecting the sync option');
- $this->line(' ');
- }
- protected function fullAnalyze()
- {
- $count = Profile::count();
- $bar = $this->output->createProgressBar($count);
- $bar->start();
- Profile::chunk(5000, function($profiles) use ($bar) {
- foreach($profiles as $profile) {
- if($profile->domain == null) {
- $bar->advance();
- continue;
- }
- $avatar = Avatar::whereProfileId($profile->id)->first();
- if(!$avatar || $avatar->cdn_url == null) {
- $this->incr('notFetched');
- }
- $this->incr('found');
- $bar->advance();
- }
- });
- $this->line(' ');
- $this->line(' ');
- $this->info('Found ' . $this->found . ' remote accounts');
- $this->info('Found ' . $this->notFetched . ' remote avatars to fetch');
- }
- protected function fetch()
- {
- $this->info('Fetching ....');
- Avatar::whereIsRemote(true)
- ->whereNull('cdn_url')
- // ->with('profile')
- ->chunk(10, function($avatars) {
- foreach($avatars as $avatar) {
- if(!$avatar || !$avatar->profile) {
- continue;
- }
- $url = $avatar->profile->remote_url;
- if(!$url || !Helpers::validateUrl($url)) {
- continue;
- }
- try {
- $res = Helpers::fetchFromUrl($url);
- if(
- !is_array($res) ||
- !isset($res['@context']) ||
- !isset($res['icon']) ||
- !isset($res['icon']['type']) ||
- !isset($res['icon']['url']) ||
- !Str::endsWith($res['icon']['url'], ['.png', '.jpg', '.jpeg'])
- ) {
- continue;
- }
- } catch (\GuzzleHttp\Exception\RequestException $e) {
- continue;
- } catch(\Illuminate\Http\Client\ConnectionException $e) {
- continue;
- }
- $avatar->remote_url = $res['icon']['url'];
- $avatar->save();
- RemoteAvatarFetch::dispatch($avatar->profile);
- }
- });
- }
- protected function fix()
- {
- Profile::chunk(5000, function($profiles) {
- foreach($profiles as $profile) {
- if($profile->domain == null || $profile->private_key) {
- continue;
- }
- $avatar = Avatar::whereProfileId($profile->id)->first();
- if($avatar) {
- continue;
- }
- $avatar = new Avatar;
- $avatar->is_remote = true;
- $avatar->profile_id = $profile->id;
- $avatar->save();
- $this->incr('fixed');
- }
- });
- $this->line(' ');
- $this->line(' ');
- $this->info('Fixed ' . $this->fixed . ' accounts with a blank avatar');
- }
- protected function sync()
- {
- Avatar::whereIsRemote(true)
- ->with('profile')
- ->chunk(10, function($avatars) {
- foreach($avatars as $avatar) {
- RemoteAvatarFetch::dispatch($avatar->profile);
- }
- });
- }
- }
|