Maintain local ⭤ remote in sync with automatic AT Protocol parity for Laravel (alpha & unstable)
at dev 4.2 kB view raw
1<?php 2 3namespace SocialDept\AtpParity\Commands; 4 5use Illuminate\Console\Command; 6use SocialDept\AtpParity\Import\ImportState; 7 8use function Laravel\Prompts\info; 9use function Laravel\Prompts\note; 10use function Laravel\Prompts\table; 11use function Laravel\Prompts\warning; 12 13class ImportStatusCommand extends Command 14{ 15 protected $signature = 'parity:import-status 16 {did? : Show status for specific DID} 17 {--pending : Show only pending/incomplete imports} 18 {--failed : Show only failed imports} 19 {--completed : Show only completed imports}'; 20 21 protected $description = 'Show import status'; 22 23 public function handle(): int 24 { 25 $did = $this->argument('did'); 26 27 if ($did) { 28 return $this->showDidStatus($did); 29 } 30 31 return $this->showAllStatus(); 32 } 33 34 protected function showDidStatus(string $did): int 35 { 36 $states = ImportState::where('did', $did)->get(); 37 38 if ($states->isEmpty()) { 39 note("No import records found for {$did}"); 40 41 return self::SUCCESS; 42 } 43 44 info("Import status for {$did}"); 45 46 table( 47 headers: ['Collection', 'Status', 'Synced', 'Skipped', 'Failed', 'Started', 'Completed'], 48 rows: $states->map(fn (ImportState $state) => [ 49 $state->collection, 50 $this->formatStatus($state->status), 51 $state->records_synced, 52 $state->records_skipped, 53 $state->records_failed, 54 $state->started_at?->diffForHumans() ?? '-', 55 $state->completed_at?->diffForHumans() ?? '-', 56 ])->toArray() 57 ); 58 59 return self::SUCCESS; 60 } 61 62 protected function showAllStatus(): int 63 { 64 $query = ImportState::query(); 65 66 if ($this->option('pending')) { 67 $query->incomplete(); 68 } elseif ($this->option('failed')) { 69 $query->failed(); 70 } elseif ($this->option('completed')) { 71 $query->completed(); 72 } 73 74 $states = $query->orderByDesc('updated_at')->limit(100)->get(); 75 76 if ($states->isEmpty()) { 77 note('No import records found'); 78 79 return self::SUCCESS; 80 } 81 82 $this->displaySummary(); 83 84 table( 85 headers: ['DID', 'Collection', 'Status', 'Synced', 'Updated'], 86 rows: $states->map(fn (ImportState $state) => [ 87 $this->truncateDid($state->did), 88 $state->collection, 89 $this->formatStatus($state->status), 90 $state->records_synced, 91 $state->updated_at->diffForHumans(), 92 ])->toArray() 93 ); 94 95 if ($states->count() >= 100) { 96 note('Showing first 100 results. Use --pending, --failed, or --completed to filter.'); 97 } 98 99 return self::SUCCESS; 100 } 101 102 protected function displaySummary(): void 103 { 104 $counts = ImportState::query() 105 ->selectRaw('status, count(*) as count') 106 ->groupBy('status') 107 ->pluck('count', 'status'); 108 109 $pending = $counts->get('pending', 0); 110 $inProgress = $counts->get('in_progress', 0); 111 $completed = $counts->get('completed', 0); 112 $failed = $counts->get('failed', 0); 113 114 info("Import Status Summary"); 115 note("Pending: {$pending} | In Progress: {$inProgress} | Completed: {$completed} | Failed: {$failed}"); 116 117 if ($failed > 0) { 118 warning("Use 'php artisan parity:import --resume' to retry failed imports"); 119 } 120 121 $this->newLine(); 122 } 123 124 protected function formatStatus(string $status): string 125 { 126 return match ($status) { 127 ImportState::STATUS_PENDING => 'pending', 128 ImportState::STATUS_IN_PROGRESS => 'running', 129 ImportState::STATUS_COMPLETED => 'done', 130 ImportState::STATUS_FAILED => 'FAILED', 131 default => $status, 132 }; 133 } 134 135 protected function truncateDid(string $did): string 136 { 137 if (strlen($did) <= 30) { 138 return $did; 139 } 140 141 return substr($did, 0, 15).'...'.substr($did, -12); 142 } 143}